在我的应用程序中,客户端有一个持久化实体的副本,存储在一个集合中,以便最大限度地减少数据库事务。由于它是一个多用户系统,另一个用户可能正在查看同一个对象,让我们说一个任务实体。假设第二个用户在您查看任务时从数据库中删除了该任务,并且您决定也将其删除。当您尝试删除它时,我得到一个StackOverflowError,当然还没有执行删除(因为已经删除了任务)。有没有办法使用数据库,jpa或hibernate异常来捕获这个?我正在使用entitymanager obects删除实体。
public <T> void remove(T entity) throws PersistenceException{
log.debug("Removing entity of type " + entity.getClass().getName());
// TODO add exception handling
EntityManager em = createEntityManager();
em.getTransaction().begin();
em.remove(em.merge(entity));
em.getTransaction().commit();
em.close();
}
答案 0 :(得分:1)
这里有一个乐观的锁定问题。这不仅仅是删除会很麻烦。可能有两个或更多人编辑同一个实体(或者一个人会编辑一个实体,另一个人会删除它,最终结果应该是什么?)。
在您的情况下,在删除实体之前,您需要先在事务中加载它。如果找不到,有人已将其删除。否则你可以安全地将其删除。
答案 1 :(得分:0)
如果您正在寻找异常;那么你可以试试如下 -
public <T> void remove(T entity) throws PersistenceException{
log.debug("Removing entity of type " + entity.getClass().getName());
EntityManager em =null;
EntityTransaction et=null;
try{
em = createEntityManager();
et=em.getTransaction();
if(!et.isActive()){ // you should have new txn always. else throw expception
et.begin();
.... // your remove logic
et.commit();
em.close();
} else{
et.setRollbackOnly();
throw new RunTimeException(..); //optional throw
}
}catch(Exception e) {
et.rollback();
throw new RunTimeException(...)..; //optional throw
}