почему JPA может сохранить мою сущность, но не может удалить сущность? - PullRequest
2 голосов
/ 22 июня 2011

В моем проекте JSF2-JPA2-Spring3 я могу вставлять новые объекты, но не могу удалять объекты.Это сообщение об ошибке: java.lang.IllegalArgumentException: удаление отдельного экземпляра объекта. Entity # 8

Это мой файл persistence.xml:

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

http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version = "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 ]

4 голосов
/ 22 июня 2011

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

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

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

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

2 голосов
/ 22 июня 2011

Кроме того, вы можете удалить свою сущность с небольшим количеством JPQL:

public void delete(Entity entity) {
    em.createQuery("DELETE FROM Entity e WHERE e.id = :id")
            .setParameter("id", entity.getId())
            .executeUpdate();
}
0 голосов
/ 13 августа 2013

Существует несколько руководств по реализации общих DAO:

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

Я получил то же самое Устранение ошибки отсоединенной сущности экземпляра , поэтому я изменил ее на:

public void delete(T entity) {
    T eT = entityManager.merge(entity);
    entityManager.remove(eT);
}
0 голосов
/ 21 февраля 2013

Еще один способ сделать это может быть:

Entity newEntity = entityManager.getReference(Entity.class, entity.getId());
entityManager.remove(newEntity);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...