2011-06-22 52 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); 
}