有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java Spring(LinkedHash)映射中的枚举键未排序

我的实体Mealplan有一个mealsPerWeek属性作为LinkedHashMap

@Entity
public class Mealplan {

@Id
private int id;

@ManyToMany
private Map<Weekday, Meal> mealsPerWeek = new LinkedHashMap<>();

public Map<Weekday, Meal> getMealsPerWeek() {
    return mealsPerWeek;
}

}

map属性的键是Weekday,是一个枚举:

public enum Wochentag {
    Monday, Tuesday, Wednesday, Thursday, Friday
}

现在,我希望在我的API中,餐食按照枚举的正确顺序显示。但它的显示非常随机:

{
id: 1,
mealsPerWeek: {
  Tuesday: {
   id: 3,
   name: "Salad",
   preis: 3,
   art: "vegan"
},
  Monday: {
   id: 4,
   name: "Linsensuppe",
   preis: 23.5,
   art: "vegan"
},

如何在REST API中对其进行排序,使其以正确的顺序显示密钥

编辑:每次启动应用程序时,我都通过data.sql插入对象,并意识到每次顺序都不同

源代码:https://gitlab.com/joshua.olberg/java-spring-backend


共 (2) 个答案

  1. # 1 楼答案

    问题是,当从数据库加载映射(通常是所有集合)时,hibernate使用自己的集合类型

    https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/chapters/domain/collections.html

    Hibernate uses its own collection implementations which are enriched with lazy-loading, caching or state change detection semantics. For this reason, persistent collections must be declared as an interface type. The actual interface might be java.util.Collection, java.util.List, java.util.Set, java.util.Map, java.util.SortedSet, java.util.SortedMap or even other object types (meaning you will have to write an implementation of org.hibernate.usertype.UserCollectionType).

    As the following example demonstrates, it’s important to use the interface type and not the collection implementation, as declared in the entity mapping.

    Example 1. Hibernate uses its own collection implementations

    @Entity(name = "Person")
    public static class Person {
        @Id
        private Long id;
    
      @ElementCollection
        private List<String> phones = new ArrayList<>();
    
      public List<String> getPhones() {
            return phones;
        }
    }
    
    Person person = entityManager.find( Person.class, 1L );
    //Throws java.lang.ClassCastException: org.hibernate.collection.internal.PersistentBag cannot be cast to java.util.ArrayList
    ArrayList<String> phones = (ArrayList<String>) person.getPhones();
    

    因此:

    private Map<Weekday, Meal> mealsPerWeek = new LinkedHashMap<>();
    

    将被PersistentMap替换。 这就是为什么使用EnumMap或TreeMap初始化映射失败的原因

    您希望Hibernate使用PersistentSortedMap,为此

    • 使用正确的接口SortedMap
    • 添加@SortNatural@SortComparator