Java 正在从已删除的数据库中删除实体

Java 正在从已删除的数据库中删除实体,java,hibernate,jpa,Java,Hibernate,Jpa,在我的应用程序中,客户端有一个持久化实体的副本,存储在一个集合中,以便最小化数据库事务。由于它是一个多用户系统,另一个用户可能正在查看同一个对象,比如说与您一起查看任务实体。假设第二个用户在您查看任务时从数据库中删除了该任务,并且您也决定将其删除。当您试图删除它时,我得到了一个StackOverflowerError,当然不会执行删除操作(因为任务已被allready删除)。有没有一种方法可以使用数据库、jpa或hibernate异常捕捉到这种情况?我正在使用entitymanager对象删除实

在我的应用程序中,客户端有一个持久化实体的副本,存储在一个集合中,以便最小化数据库事务。由于它是一个多用户系统,另一个用户可能正在查看同一个对象,比如说与您一起查看任务实体。假设第二个用户在您查看任务时从数据库中删除了该任务,并且您也决定将其删除。当您试图删除它时,我得到了一个StackOverflowerError,当然不会执行删除操作(因为任务已被allready删除)。有没有一种方法可以使用数据库、jpa或hibernate异常捕捉到这种情况?我正在使用entitymanager对象删除实体

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();
}
public void remove(T实体)抛出PersistenceException{
log.debug(“删除类型为“+entity.getClass().getName()的实体”);
//TODO添加异常处理
EntityManager em=createEntityManager();
em.getTransaction().begin();
em.remove(em.merge(entity));
em.getTransaction().commit();
em.close();
}

如果要捕获异常;那么你可以试试下面的方法--

public void remove(T实体)抛出PersistenceException{
log.debug(“删除类型为“+entity.getClass().getName()的实体”);
EntityManager em=null;
EntityTransaction et=null;
试一试{
em=createEntityManager();
et=em.getTransaction();
如果(!et.isActive()){//您应该始终拥有新的txn。否则将抛出expection
等开始();
..//删除您的逻辑
et.commit();
em.close();
}否则{
et.setRollbackOnly();
抛出新的RunTimeException(..);//可选抛出
}
}捕获(例外e){
et.rollback();
抛出新的RunTimeException(…)…;//可选抛出
}

您遇到的是一个乐观锁定问题。不仅删除会带来麻烦。可能还会有两个或两个以上的人编辑同一个实体(或者一个人编辑一个实体,另一个人删除它,最终结果应该是什么?)

在您的情况下,在删除实体之前,您需要先将其加载到事务中。如果找不到,则表示有人已将其删除。否则,您可以安全地将其删除

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
}