假设你有一堆Article对象,带有“title”属性。然后是一个带有TITLE列的ARTICLE表。 TITLE列具有唯一约束。
用户界面在一个页面上显示所有文章,并带有用于编辑标题的文本字段。
想象一下你有两篇文章X& Y,X具有标题“1”,Y具有标题“2”。在页面中,您将Y重命名为“2”,将X重命名为“1”,然后提交表单。将表单中的值直接复制到hibernate对象并保存,将发生ConstraintViolationException。
如果您从集合中删除“1”文章,然后添加标题为“1”的另一篇文章并保存该集合,也会发生这种情况。
那么处理这个Hibernate怪癖的最佳方法是什么?我觉得我应该重新安排UI或其他东西。在保存hibernate对象之前手动检查这些条件似乎有点麻烦。
答案 0 :(得分:0)
我的猜测是,您尝试一次更新每个实例,从而实际碰撞唯一属性。
查看每个查询之间是否正在关闭或刷新Session
对象。在这种情况下,您必须在关闭/刷新之前更改两个实例。
编辑:请务必阅读我发布的下一个答案。
答案 1 :(得分:0)
尽管我之前的回答是,但我确认,即使您在一次传递中,也会对两个持久实体的唯一字段进行排列会产生约束违规错误。
因此,我想说解决这个问题的最简单方法是不允许任何更改意味着字段违反了唯一约束,即使最终结果有效即可。在UI层中进行编码应该相当简单。
似乎至少MySQL受此限制,因为我发现here,显然没有一种简单的方法可以在没有严重性能损失的情况下解决这个问题。
因此人们会认为这个问题可以通过编程方式轻松解决。它很糟糕,是的,但是应该能够编写一些简单的代码来检查您的更新是否会置换两个现有的唯一字段,并分两步完成。
但是,它可能变得毛茸茸。想象一下,排列3个实例而不是2个实例。例如,“A”,“B”,“C”变为“B”,“C”,“A”。三个步骤?下一步是什么?