如何在 @OneToMany 中使用 LinkedHashSet 的插入顺序

How to use the insertion order of a LinkedHashSet in @OneToMany

我拥有的是一个有很多事件的应用程序。这些事件按时间顺序排列,但我得到的只是一个 JSON 事件代码数组,因此数组顺序是它们的添加顺序。

从我在 google 上找到的内容来看,hibernate 似乎更喜欢 Sets 而不是 Lists 但是使用 Set 我需要维护我选择使用 LinkedHashSet 的条目,因为它维护插入顺序(基于大量的 SO 问题)。

这是我的问题所在。我在 applicationEvent 的序列上设置了一个 OrderBy,它是该对象的 JSON 数组的索引(插入数据库似乎是随机的,因此使用 Id 不起作用)。查看生成的休眠 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 问题的方式。

我认为您需要将 applicationEvents 集合的类型定义从 Set 更改为 List。你试过了吗?

示例:

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;
}

尝试三种解决方法中的任何一种

1) 合并子项而不是父项

2) 在合并父项之前保留子项

3) 删除 Cascade.ALL