gpt4 book ai didi

java - JPA EntityManager persist() 导致对象出现分离,即使抛出错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:26:45 25 4
gpt4 key购买 nike

您好,我有一个具有以下功能的简单 DAO。

    public element createElement(Element e){

em.persist(e);
em.flush();

return e;
}

实体表对 (type,value) 对有唯一约束,我在下面进行测试:

    public void testCreateElement() throws DataAccessException {
// Start with empty Element table

Element e = new Element();
e.setType(myType.OTHER);
e.setValue("1");
dao.createElement(e);

e = new Element();
e.setType(MyType.OTHER);
e.setValue("1");
try{
// this should violate unique constraint of database.
dao.createElement(e);
} catch (Exception ex) {
System.out.println(ex);
}

e.setValue("2");
try{
// I expect this to work as there is no element with these values.
dao.createElement(e);
} catch (Exception ex) {
System.out.println(ex);
}
}

我的第一个捕获错误如我所料发生,因为我知道我违反了约束,就我而言,第二个 try/catch 不应该抛出错误,但它确实发生了,我得到的是这个:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.mypackage.Element

所以似乎在“e”上调用 persist(),即使它没有持久化,也会导致 hibernate 认为它是一个分离的实体。

这很烦人,因为处理 ConstraintViolation 异常的 JSF 前端正在使用这些函数,但故意保留对象以便用户可以更改其中一个字段并重试,他们得到分离实体错误。

这种行为是否是一个 hibernate 错误,因为我认为它真的不应该这样做?在 DAO 级别是否有解决此问题的方法,以便持久化不会将我的对象视为分离的,如果它实际上没有持久化?

问候,

格伦 x

最佳答案

Hibernate 抛出的异常是不可恢复的。当发生此类异常时,您唯一应该做的就是回滚事务并关闭 session 。这种异常发生后 session (及其实体)的状态是不稳定的。

如果你想保持元素的副本不变,请使用 merge() 而不是 persist(),或者在持久化之前克隆元素。

请注意,异常是预料之中的,因为当 Hibernate 持久化并刷新实体时,它首先生成一个 ID 并将该 ID 分配给实体,然后插入导致异常的行。因此,在异常之后,该实体分配了一个 ID,因此被 Hibernate 视为一个分离的实体。您可以尝试将 ID 重置为 null 并查看它是否有效,但我更愿意在使用合并之前克隆实体。

关于java - JPA EntityManager persist() 导致对象出现分离,即使抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9434164/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com