从已删除的数据库中删除实体

时间:2015-06-25 08:04:53

标签: java hibernate jpa

在我的应用程序中,客户端有一个持久化实体的副本,存储在一个集合中,以便最大限度地减少数据库事务。由于它是一个多用户系统,另一个用户可能正在查看同一个对象,让我们说一个任务实体。假设第二个用户在您查看任务时从数据库中删除了该任务,并且您决定也将其删除。当您尝试删除它时,我得到一个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();
}

2 个答案:

答案 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
}