开发者

why JPA can save my entity but It can't delete the entity?

开发者 https://www.devze.com 2023-03-14 18:39 出处:网络
In my JSF2-JPA2-Spring3 project, I can insert new entities but can\'t remove entities. This is the error message: java.lang.IllegalArgumentException: Removing a detached instance entity.Entity#8

In my JSF2-JPA2-Spring3 project, I can insert new entities but can't remove entities. This is the error message: java.lang.IllegalArgumentException: Removing a detached instance entity.Entity#8

This is my 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>

This is my service:

@Service("myService")

public class MyServiceImpl implements MyService {

@R开发者_开发技巧esource(name="MyRepository")
MyDAO myDao;

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

This is my dao:

@Repository("MyRepository")

public class 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);
    }
}

This is 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>

I try to remove an entity from a list that feed using this method in 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;
}


The error is telling you that the entity you are trying to delete can't be deleted because it isn't associated with the current persistence context. This can happen if you read the entity in one transaction and then try to delete (or update it) in another transaction, because the persistence context is scoped to the transaction.

To fix it, change your DAO to first merge the entity back into the persistence context, then delete it:

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

Note: EntityManager.merge() returns an entity that is part of the current persistence context - the entity you pass in is still detached.


Alternatively, you can delete your entity with a bit of JPQL:

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


Another way to do that can be:

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


There are some tutorials around for Generic DAO implementations:

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

I got the same Removing a detached instance entity error, so I changed it to:

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

精彩评论

暂无评论...
验证码 换一张
取 消