2013-02-02 36 views
0

继实体罚球和删除时出现错误:理解:“无法执行分离对象上操作删除”

实体:

@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. 实体服务器被删除

    ...相同道

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

    这将抛出类似的异常:

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而不需要刷新实体。

+0

是您使用的Spring @Transactional注释吗? – Shaun

回答

1

假设你使用Spring的@Transactional注解,它不能拦截来自注释对象实例内的调用(由于Spring使用AOP的动态代理和方法拦截)。尝试从服务层调用并在其中注释该方法。

如果您不使用Spring,那么您可能希望使用@TransactionAttribute,这是类似于Java EE的批注。

+0

你说得对,我们在Dao使用@Transactional。但我不明白*它不能拦截来自注释对象*的实例内的调用。什么是你的“注释对象”?道?我没有在dao内部调用“deleteHardJUnit”,一个JUnit测试运行并首先调用update,然后在几行后调用“deleteHardJUnit”。什么会阻止任何拦截器行为正确? –

+0

和解决方案是什么?写一个JPQL“通过ID删除”语句?或者在我删除之前每次调用EntityManager.merge(实体)都是我猜测的另一个选项。 –

相关问题