有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java解析JPA/Hibernate EntityNotFoundException

我遇到了一个非常奇怪的情况。当我尝试删除一组实体时&;紧接着尝试添加另一组实体,它们可能有也可能没有相同的元素,我似乎得到了下面的例外。整个堆栈跟踪是不需要的,因为它没有说太多

javax.persistence.EntityNotFoundException: deleted entity passed to persist [com.test.MyEntity#<null>]

为了让我自己更清楚,让我做一个更详细的解释

这是我的实体

@Entity
@Table(name = "MY_ENTITY")
@SequenceGenerator(name = "my_enty_seq", sequenceName = "MY_ENTITY_SEQ")
public class MyEntity {

    private long id;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "my_enty_seq")
    @Column(name = "ID", unique = true, nullable = false, precision = 12, scale = 0)
    public long getId() {
        return this.id;
    }

    // Other methods & variables which are not relevant here.
}

这是一个处理实体的类

public class MyEntityServiceImpl implements MyEntityService {

    public void updateMyEntities(List<MyEntity> newEntities) {

        // Delete the Old Items
        List<MyEntity> oldEntities = myDAO.getAllEntities();
        myDAO.delete(oldEntities); // myDAO extends GenericDaoJpaWithoutJpaTemplate, hence, the DELETE is available in it.

        // Add the New Items
        myDAO.store(newEntities); // This is where I get the mentioned Exception.
    }

    // Other non-relevant stuffs
}

我在store()方法上得到提到的异常的场景是,在oldEntitiesnewEntities列表中都存在一些公共的MyEntity对象

我尝试了很多方法来解决这个问题,但是没有任何方法可以帮助我克服这个问题。加入FetchType.EAGER&CascaseType.ALL, CascaseType.PERSIST也不起作用。jpaEntityManager似乎也没有commit()方法,我可以在delete()之后使用&;在store()方法之前。我也尝试过将store()persist()交换(尽管存储内部调用persist()!)

注意:-要求删除旧列表并插入新列表,因为比较元素并只添加新元素是乏味的(列表有时可能非常庞大)


共 (2) 个答案

  1. # 1 楼答案

    我已经想出了一个办法。我使用了flushAndClear()方法而不是flush()方法

    似乎flush()只将持久性缓存与数据库同步,但没有将其清除

    另一方面,执行所有挂起的操作,然后清除所有内容

    引用delete方法的org.crank.crud.GenericDao<T, PK extends Serializable>源代码中的java文档

    Remove an object from persistent storage in the database. Since this uses the PK to do the delete there is a chance that the entity manager could be left in an inconsistent state, if you delete the object with id 1 but that object is still in the entity managers cache.

    You can do two things, put all your PK deletes together and then call flushAndClear when done, or you can just call the delete method with the entity which will not suffer from this problem.

    我尝试了使用flushAndClear()方法的第一个选项,它按预期工作

  2. # 2 楼答案

    我认为,例外情况很明显:您告诉会话删除实体X,同时存储实体X。现在,可怜的家伙感到困惑,不知道该怎么办

    在持久化新/旧/已删除的实体之前,可能通过commit执行Session.flush()

    编辑:

    如果这不起作用,则需要在新会话中进行插入。问题可能仍然是,您并没有一个临时实体,但实际上删除了一个。因此,您可能必须将所有数据复制到新实例中