2011-06-22 2 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 {

private EntityManager entityManager; 

@PersistenceContext 
public void setEntityManager(EntityManager entityManager) { 
    this.entityManager = entityManager; 
} 

public void delete(Entity entity) throws Exception { 

    try { 
     entityManager.remove(entity); 
    } catch (DataAccessException e) { 
     throw new Exception(e); 
    } 
} 

Это 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> 

Я стараюсь, чтобы удалить объект из списка, питающихся с помощью этого метода в дао:

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

ошибка говорит вам, что сущность, которую вы пытаетесь удалить не может быть удален, потому что ISN 't, связанный с текущим контекстом постоянства. Это может произойти, если вы прочитали объект в одной транзакции и затем попытаетесь удалить (или обновить его) в другой транзакции, потому что контекст персистентности привязан к транзакции.

Чтобы это исправить, изменить DAO на первый сливаться объект обратно в контекст сохранения, а затем удалить его:

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

Примечание: EntityManager.merge() возвращает объект, который является частью текущей настойчивостью контекст - объект, который вы передаете, все еще отсоединен.

+0

Спасибо. Но когда я это делаю: entityManager.merge (entity); \t \t \t entityManager.удалить (юридическое лицо); такая же ошибка произошла! – nazila

+0

Я очистил свой образец кода, чтобы сделать его более читаемым. Прочтите примечание еще раз - вы не можете вызывать слияние на сущности, а затем удалить тот же объект, вы должны использовать объект, который возвращается из merge(). –

+0

Спасибо. Теперь он работает правильно, но есть ли какой-либо метод в этой конфигурации. Итак, мне не нужно сначала объединять мою сущность, чтобы выполнить операцию dao на моих сущностях? Я чувствую, что это не лучшая практика. – 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

Есть некоторые учебники вокруг для реализаций Generic DAO:

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

Я получил то же самое Снятие ошибки отдельного экземпляра объекта, поэтому я изменил его на:

public void delete(T entity) { 
    T eT = entityManager.merge(entity); 
    entityManager.remove(eT); 
} 
Смежные вопросы