理解:“无法对分离的对象执行操作删除”

时间:2013-02-02 03:00:03

标签: java jpa entity openjpa

以下实体抛出和删除时出错:

实体:

@Entity
@NamedQueries({
})
public class Server {
   //some attributes
}

我遵循了非常简单的JUnit测试,它执行以下操作:

  1. 已创建实体服务器
    @Transactional
    public class ServerDao {
    public Server update(Server entity, long userId) {
        entity.setDeleted(false);
        if (entity.getId() > 0) {
            if (userId > 0) {
                entity.setUpdated(new Date());
                entity.setUpdatedby(usersDao.get(userId));
            }
            em.merge(entity);
        } else {
            if (userId > 0) {
                entity.setInserted(new Date());
                entity.setInsertedby(usersDao.get(userId));
            }
            em.persist(entity);
        }
        return entity;
        }
    }
    
  2. 删除实体服务器

    ......同样的Dao

    public void deleteHardJUnit(Server entity) {
        em.remove(entity);
    }
    

    这将抛出一个例外:

  3.   

      org.apache.openjpa.persistence.ArgumentException:你无法执行   删除已分离的对象   " org.apache.openmeetings.persistence.beans.basic.Server-1"

    如果我将删除方法更改为:

    public void deleteHardJUnit(Server entity) {
        if (entity.getId() > 0) {
            em.refresh(entity);
            em.remove(entity);
        }
    }
    

    一切"似乎"按预期工作,不会抛出任何异常,并从数据库中删除记录。

    但是我不确定这应该是什么意思,我们真的需要在删除之前刷新每个实体吗?因为我以前多次使用EntityManager.delete而无需刷新实体。

1 个答案:

答案 0 :(得分:1)

假设您正在使用Spring的@Transactional注释,它无法拦截来自注释对象实例内的调用(由于Spring使用动态代理进行AOP和方法拦截)。尝试从服务层调用并在那里注释方法。

如果您没有使用Spring,那么您可能希望使用@TransactionAttribute,这是一个类似Java EE的注释。