Java Spring: Enum keys in (LinkedHashMap are not ordered
Java Spring: Enum keys in (LinkedHash)Map are not ordered
我的实体 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;
}
}
映射属性的键是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
插入对象并意识到,每次顺序都是不同的。
EnumMap 在这里可能对您有所帮助。迭代顺序基于枚举中声明的顺序 - https://docs.oracle.com/javase/7/docs/api/java/util/EnumMap.html
问题是当从 db 加载地图(通常是所有集合)时,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 初始化 Map 失败的原因。
您希望 Hibernate 使用 PersistentSortedMap,为此
- 使用正确的界面
SortedMap
- 添加
@SortNatural
或@SortComparator
我的实体 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;
}
}
映射属性的键是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
插入对象并意识到,每次顺序都是不同的。
EnumMap 在这里可能对您有所帮助。迭代顺序基于枚举中声明的顺序 - https://docs.oracle.com/javase/7/docs/api/java/util/EnumMap.html
问题是当从 db 加载地图(通常是所有集合)时,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 初始化 Map 失败的原因。
您希望 Hibernate 使用 PersistentSortedMap,为此
- 使用正确的界面
SortedMap
- 添加
@SortNatural
或@SortComparator