从集合中间删除元素时,Hibernate会导致合并包含有序集合的对象的痛苦。
一些背景知识:我正在开发一种生成CSV报告的工具。在我的模型中,我希望报表对象具有列对象,其顺序由column.orderIndex int值指定。
当我删除orderIndex不是列表中的最后一列的列时出现问题。执行merge()时,Hibernate运行以下SQL:
update REPORT_COLUMNS set [...], orderIndex=1 where pkey=2 --This is formerly the 2nd column, and now it's orderIndex is going to collide with the orderIndex of the 1st
delete from REPORT_COLUMNS where pkey=1 --This is the 1st column, which is being removed
如果Hibernate首先运行删除,则不会出现问题。
以下是声明集合的方式:
@OneToMany(fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
@OrderBy("orderIndex")
@JoinColumn(name = "report", updatable = true, insertable = true, nullable = false)
@Cascade({ org.hibernate.annotations.CascadeType.DELETE,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN,
org.hibernate.annotations.CascadeType.MERGE,
org.hibernate.annotations.CascadeType.PERSIST,
org.hibernate.annotations.CascadeType.REMOVE,
org.hibernate.annotations.CascadeType.SAVE_UPDATE })
public List<ReportColumnImpl> getColumnImpls() {
return columns;
}
非常感谢您的帮助。
答案 0 :(得分:0)
最简单的解决方案是使约束延迟,即仅在事务结束时进行检查。 Oracle支持延迟约束。不知道你的数据库。
否则,您可以删除要删除的实体,然后刷新会话,然后更新orderIndexes。但是,如果Hibernate在更新第3个元素的索引之前尝试更新第4个元素的索引,则可能会遇到问题。
答案 1 :(得分:0)
您是否需要更新orderindex?
如果您删除了1个或多个元素,则此一组整数(1,2,3,4,5,6,7)仍可按相同的顺序排序。 e.g。
(1,2,5,7)
如果你确实需要维护一个订单,为什么不创建一个存储对下一列和上一列的引用的ReportColumn(很像链接列表),然后当你删除一个更新元素的任何一边?