一尘不染

Hibernate和NonUniqueObjectException

hibernate

我有一个包含其他两个具有@ManyToOne关系的实体的实体。

@Entity
public class A extends Serializable{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @Cascade(CascadeType.SAVE_UPDATE)
    private B b;

    @ManyToOne
    @Cascade(CascadeType.SAVE_UPDATE)
    private C c;

}

如果我尝试保存一个具有另一个A记录的“ B_ID”和“ C_ID”的A实例,则会出现异常:

org.hibernate.NonUniqueObjectException:具有相同标识符值的另一个对象已与会话关联

例如:

A table
|   ID  |   B_ID    |   C_ID    |
|    1  |      1    |   null    |    // this works
|    2  |   null    |      1    |    // this works
|    3  |      1    |      x    |    // this throws the exception
|    4  |      x    |      1    |    // this throws the exception

x=any value of existent B/C_ID

B_ID和C_ID在我的模型中不是唯一的,并且(B_ID + C_ID)不是唯一的约束!

我能做什么?

预先感谢。


阅读 286

收藏
2020-06-20

共1个答案

一尘不染

Hibernate在这里并没有抱怨数据库的唯一性,而是在抱怨当前Session对象已经包含了一个与您要保存的新对象具有相同ID的对象。这是不允许的-
Hibernate严格要求给定的ID不能在单个会话的范围内用两个不同的对象表示。

在某个时候,您的应用程序已保存了具有相同ID的实体,并且该对象已在会话中“注册”。在这种特定情况下,很难分辨出它在抱怨哪个ID,因为异常文本不清楚。尝试暂时删除级联伪指令,看看它是否仍然存在,请尝试缩小范围。

如有必要,您可以强制会话“忘记”给定ID的任何现有对象(Session.evict()在Hibernate
API或EntityManager.detach()JPA 2.0 API中使用),但这不是一个很好的解决方案。

重申一下-该异常与数据库约束完全无关,它与Hibernate保护其内部内存状态的一致性有关。

2020-06-20