我所拥有的是一个包含许多事件的应用程序。这些事件按时间顺序排列,但我得到的只是一个eventCodes的JSON数组,因此数组顺序是它们的添加顺序。
似乎hibernate更喜欢Set
s List
s而不是我在google和SO上找到的东西但是使用Set
我需要维护我选择的条目的顺序使用LinkedHashSet
因为它维护了插入顺序(基于大量的SO问题)。
我的问题出在哪里。我在applicationEvent的序列上设置了一个OrderBy
,它是该对象的JSON数组的索引(插入到数据库中似乎是随机的,所以使用Id不起作用)。看看hibernate生成的SQL似乎正在得到我期望的结果。所有事件按顺序1-n的顺序排列。
然而,当我循环构建一个列表时,顺序似乎是随机的,不尊重我认为合适的插入顺序。
Iterator<ApplicationEventDTO> iter = applicationEvents.iterator();
List<ApplicationEventDTO> list = new ArrayList<ApplicationEventDTO>();
while(iter.hasNext()){
list.add((ApplicationEventDTO) iter.next());
}
申请实体:
@Entity
@Table
public class Application {
//Lots of other stuff
private Set<ApplicationEvent> applicationEvents=new LinkedHashSet<ApplicationEvent>();
@OneToMany (mappedBy = "application", fetch = FetchType.EAGER
, cascade=CascadeType.ALL, orphanRemoval=true)
@NotAudited
@OrderBy("sequence")
public Set<ApplicationEvent> getApplicationEvents() {
return applicationEvents;
}
public void setApplicationEvents(Set<ApplicationEvent> applicationEvents) {
this.applicationEvents = applicationEvents;
}
}
更新
为了添加更多信息,以下文章引导我坚持使用集合列表。
https://vladmihalcea.com/hibernate-facts-favoring-sets-vs-bags/
Hibernate cannot simultaneously fetch multiple bags - 最后的评论表明,集合优于列表。
应用程序实体非常庞大,并且有很多关系。所有这些似乎都是套装。在尝试将事件更改为列表时,我收到:cannot simultaneously fetch multiple bags
这就是我发现SO问题的方式。
答案 0 :(得分:1)
I believe that you need to change the type definition of the applicationEvents
Collection, from Set
to List
. Have you tried that?
Example:
private List<ApplicationEvent> applicationEvents=new ArrayList<>();
//Need to remove FetchType when there are multiple Collections
@OneToMany (mappedBy = "application", cascade=CascadeType.ALL, orphanRemoval=true)
@NotAudited
@OrderBy("sequence")
public List<ApplicationEvent> getApplicationEvents() {
return applicationEvents;
}
Try any of the the three work arounds
1) merging the child instead of the parent
2) persisting the children prior to merging the parent
3) removing the Cascade.ALL