2011-06-22 53 views
2

在我的JSF2-JPA2-Spring3项目中,我可以插入新实体但不能删除实体。这是错误消息:java.lang.IllegalArgumentException异常:删除脱管的实例entity.Entity#8为什么JPA可以保存我的实体但它不能删除实体?

这是我的persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?> 

http://java.sun.com/xml /ns/persistence/persistence_1_0.xsd” 版本= “1.0”>

<persistence-unit name="myPersistenceUnit" 
    transaction-type="RESOURCE_LOCAL"> 
    <properties>    
     <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> 
     <property name="hibernate.show_sql" value="true" /> 
    </properties> 
</persistence-unit> 

这是我的服务:

@Service("myService") 

公共类MyServiceImpl实现为MyService {

@Resource(name="MyRepository") 
MyDAO myDao; 

@Transactional 
public void deleteEntity(Entity entity) throws DAOException { 
    myDao.delete(entity); 
} 

这是我道:

@Repository("MyRepository") 

公共类的UserDAO {

​​

这是applicationContext.xml中:

<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" > 

     </bean> 
    </property> 
    <property name="dataSource" ref="myDataSource" /> 
    <property name="persistenceUnitName" value="myPersistenceUnit"/> 
</bean> 

<bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" />  
</bean> 

<tx:annotation-driven /> 
<tx:annotation-driven transaction-manager="transactionManager"/> 


<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> 

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

<tx:advice id="transactionInterceptor" transaction-manager="transactionManager"> 
    <tx:attributes> 
     <tx:method name="*" rollback-for="Throwable" /> 
    </tx:attributes> 
</tx:advice> 
<aop:config> 
    <aop:advisor pointcut=" execution(* service.*Service.*(..))" 
     advice-ref="transactionInterceptor" /> 
</aop:config> 

我尝试从DAO使用这种方法喂列表中删除的实体:

public List<Entity> getAll() throws Exception { 
    List<Entity> list = null; 

    try { 
      list = entityManager.createQuery("Select e from Entity e").getResultList(); 
    } catch (DataAccessException e) { 
     throw new Exception(e); 
    } 

    return list; 
} 

回答

4

错误是告诉你,你想删除的实体不能因为它不是删除与当前的持久化上下文无关。如果您在一个事务中读取实体,然后尝试在另一个事务中删除(或更新它),则会发生这种情况,因为持久性上下文被限制在事务中。

要修复它,改变你的DAO先合并实体回持久化上下文,然后将其删除:

Entity newEntity = entityManager.merge(entity); 
entityManager.remove(newEntity); 

注:EntityManager.merge()返回当前的持久性的一部分实体上下文 - 您传递的实体仍然是分离的。

+0

谢谢。但是当我这样做:entityManager.merge(entity); \t \t \t entityManager。除去(实体);同样的错误发生! – nazila

+0

我清理了我的代码示例以使其更具可读性。再次阅读注释 - 您无法在实体上调用合并,然后移除该实体,您必须使用从merge()返回的实体。 –

+0

谢谢。现在它工作正常,但是在这个配置中有没有任何方法所以我不必首先合并我的实体来对我的实体进行道操作?我觉得这不是最佳做法。 – nazila

2

或者,你可以用一点JPQL的删除实体:

public void delete(Entity entity) { 
    em.createQuery("DELETE FROM Entity e WHERE e.id = :id") 
      .setParameter("id", entity.getId()) 
      .executeUpdate(); 
} 
+0

谢谢。但我想尝试像org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter但它不起作用:-(我不知道为什么?! – nazila

+0

我试图使用org.springframework.orm.jpa。 support.OpenEntityManagerInViewFilter,但它不适用于我。另外,在某些地方,我看到民间人士说,在视图模式下使用开放式数据库连接在性能和内存效率方面并不总是一个好的解决方案。如果是这样,有什么替代方案? – nazila

+0

听起来像Spring一样,最明显的选择是你只是不使用它,这是一个以前不太相关的框架。 –

0

另一种方式来做到这一点可能是:

Entity newEntity = entityManager.getReference(Entity.class, entity.getId()); 
entityManager.remove(newEntity); 
0

有一些教程各地的通用DAO实现:

public void delete(T entity) { 
    entityManager.remove(entity); 
} 

我得到了相同的删除分离的实例实体错误,所以我将它改为:

public void delete(T entity) { 
    T eT = entityManager.merge(entity); 
    entityManager.remove(eT); 
}