Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring(LinkedHash)映射中的枚举键未排序_Java_Spring_Spring Boot_Spring Data Jpa_Spring Rest - Fatal编程技术网

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

Java Spring(LinkedHash)映射中的枚举键未排序,java,spring,spring-boot,spring-data-jpa,spring-rest,Java,Spring,Spring Boot,Spring Data Jpa,Spring Rest,我的实体Mealplan有一个mealsPerWeek属性作为LinkedHashMap @Entity public class Mealplan { @Id private int id; @ManyToMany private Map<Weekday, Meal> mealsPerWeek = new LinkedHashMap<>(); public Map<Weekday, Meal> getMealsPerWeek() { retur

我的实体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;
}

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

{
id: 1,
mealsPerWeek: {
  Tuesday: {
   id: 3,
   name: "Salad",
   preis: 3,
   art: "vegan"
},
  Monday: {
   id: 4,
   name: "Linsensuppe",
   preis: 23.5,
   art: "vegan"
},
我如何在RESTAPI中对其排序,以便它以正确的顺序显示键

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


源代码:

EnumMap可能会在这里帮助您。迭代顺序基于Enum中声明的顺序-

EnumMap在此可能会帮助您。迭代顺序基于枚举中声明的顺序-

问题在于,当加载映射时,通常是从db加载所有集合时,hibernate使用自己的集合类型

Hibernate使用自己的集合实现,这些集合实现丰富了延迟加载、缓存或状态更改检测语义。因此,必须将持久集合声明为接口类型。实际接口可能是java.util.Collection、java.util.List、java.util.Set、java.util.Map、java.util.SortedSet、java.util.SortedMap,甚至是其他对象类型,这意味着您必须编写org.hibernate.usertype.UserCollectionType的实现

正如下面的示例所示,重要的是使用接口类型,而不是实体映射中声明的集合实现

例1。Hibernate使用自己的集合实现

@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,为此

使用正确的界面分类图 添加@SortNatural或@SortComparator
问题是,当加载映射和数据库中的所有集合时,hibernate使用自己的集合类型

Hibernate使用自己的集合实现,这些集合实现丰富了延迟加载、缓存或状态更改检测语义。因此,必须将持久集合声明为接口类型。实际接口可能是java.util.Collection、java.util.List、java.util.Set、java.util.Map、java.util.SortedSet、java.util.SortedMap,甚至是其他对象类型,这意味着您必须编写org.hibernate.usertype.UserCollectionType的实现

正如下面的示例所示,重要的是使用接口类型,而不是实体映射中声明的集合实现

例1。Hibernate使用自己的集合实现

@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,为此

使用正确的界面分类图 添加@SortNatural或@SortComparator
LinkedHashMap按键插入映射的顺序排序。它没有分类。您希望在创建新对象或查询Mealplan时对其进行排序吗?问题在于,尽管迭代顺序是填充顺序,但填充是由JPA实现Hibernate或您正在使用的任何东西完成的。这不是一个答案,因为我不知道如何将排序顺序应用于实体中的映射字段,但有人会知道。谢谢您的快速回答。那么,在客户端对密钥进行排序是否更好@Lesiak是的,我希望在创建新对象时对其进行排序。但它将始终是相同的顺序,并且每个键始终是一个对象。您可以对enum使用order值,并对order值使用带comparator的treemap。您说创建新对象时vorderbis是错误的。这是令人惊讶的。你能告诉我们你是如何构建它的吗?LinkedHashMap是按键插入到映射中的顺序排列的。它没有分类。您希望在创建新对象或查询Mealplan时对其进行排序吗?问题在于,尽管迭代顺序是填充顺序,但填充是由JPA实现Hibernate或您正在使用的任何东西完成的。这不是一个答案,因为我不知道如何将排序顺序应用于实体中的映射字段,但有人会知道。谢谢您的快速回答。那么,在客户端对密钥进行排序是否更好@Lesiak是的,我希望在创建新对象时对其进行排序。但它将始终是相同的顺序,并且每个键始终是一个对象。您可以对enum使用order值,并对order值使用带comparator的treemap。您说创建新对象时vorderbis是错误的。这是令人惊讶的。您能告诉我们您是如何构建它的吗?我制作了:private Map mealsPerWeek=new EnumMapWeekday.class;但它仍然没有分类/啊,该死的,我以为这样就可以了-对不起。现在我很好奇为什么它不能工作,但我的笔记本电脑却不在手边。我很想在ObjectMapper中插入一个断点

看看它是如何序列化地图的,或者只是看看源代码。嗯,用我的手机快速查看GitHub上的源代码会让我觉得调试更容易到达正确的位置。嘿,我已经在开始代码中添加了我的源代码,但你可能会感到困惑,因为有些关键词是德语的,我做了:private Map mealsPerWeek=new EnumMapWeekday.class;但它仍然没有分类/啊,该死的,我以为这样就可以了-对不起。现在我很好奇为什么它不能工作,但我的笔记本电脑却不在手边。我很想在ObjectMapper中插入一个断点来查看它是如何序列化该映射的,或者只是查看源代码。嗯,用我的手机快速查看GitHub上的源代码会让我觉得调试更容易到达正确的位置。嘿,我已经在开始代码中添加了源代码,但你可能会感到困惑,因为有些关键词是德语的,所以Hibernate会遵守分类地图声明吗?我想这不会有帮助,因为它会定义排序顺序。真烦人@Chris:你可以通过注释SortNatural或SortComparator来定义排序顺序,也有排序,但不推荐使用,谢谢你的详细回答!有趣的事实:在不改变其他代码或接口的情况下使用@SortNatural也能让它工作。你知道为什么吗?如果可行,我可以继续使用LinkedHashMap吗?我鼓励您保持界面、实现和hibernate实现同步。这边走。代码中使用New创建的新实例使用的是您定义的iElementation,而不是hibernate实例,它们的行为将与从db加载的实例一致。2.插装已经让人困惑,我敢打赌,如果你在上面添加不一致的类型,那么维护这段代码的人会非常感激,因为你没有参与混淆代码的竞争,是吗?@Lesiak Yes。TreeMap确实与@SortNatural注释一起工作-我注意到HashMap可以工作,但是我的@PostMap不再工作了-我想我会继续使用TreeMap。那么Hibernate会遵守SortedMap声明吗?我想这不会有帮助,因为它会定义排序顺序。真烦人@Chris:你可以通过注释SortNatural或SortComparator来定义排序顺序,也有排序,但不推荐使用,谢谢你的详细回答!有趣的事实:在不改变其他代码或接口的情况下使用@SortNatural也能让它工作。你知道为什么吗?如果可行,我可以继续使用LinkedHashMap吗?我鼓励您保持界面、实现和hibernate实现同步。这边走。代码中使用New创建的新实例使用的是您定义的iElementation,而不是hibernate实例,它们的行为将与从db加载的实例一致。2.插装已经让人困惑,我敢打赌,如果你在上面添加不一致的类型,那么维护这段代码的人会非常感激,因为你没有参与混淆代码的竞争,是吗?@Lesiak Yes。TreeMap确实与@SortNatural注释一起工作-我注意到HashMap可以工作,但是我的@PostMap不再工作了-我想我会继续使用TreeMap。