Spring 为什么JPA可以保存我的实体,但不能删除实体?

Spring 为什么JPA可以保存我的实体,但不能删除实体?,spring,jpa-2.0,Spring,Jpa 2.0,在我的JSF2-JPA2-Spring3项目中,我可以插入新实体,但不能删除实体。这是错误消息:java.lang.IllegalArgumentException:删除分离的实例实体。Entity8 这是我的persistence.xml: <?xml version="1.0" encoding="UTF-8" ?> 公共类MyServiceImpl实现了MyService{ @Resource(name="MyRepository") MyDAO myDao; @Trans

在我的JSF2-JPA2-Spring3项目中,我可以插入新实体,但不能删除实体。这是错误消息:java.lang.IllegalArgumentException:删除分离的实例实体。Entity8

这是我的persistence.xml:

<?xml version="1.0" encoding="UTF-8" ?>
公共类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>
我尝试在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;
}

错误告诉您无法删除您尝试删除的实体,因为它与当前持久性上下文不关联。如果您在一个事务中读取该实体,然后在另一个事务中尝试删除或更新它,则可能会发生这种情况,因为持久性上下文的作用域是该事务

要修复此问题,请将DAO更改为首先将实体合并回持久性上下文,然后将其删除:

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

注意:EntityManager.merge返回一个实体,该实体是当前持久性上下文的一部分-您传入的实体仍处于分离状态。

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

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

另一种方法是:

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

有一些关于一般DAO实现的教程:

public void delete(T entity) {
    entityManager.remove(entity);
}
我在删除分离的实例实体错误时得到了相同的结果,因此我将其更改为:

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

谢谢。但是当我这样做的时候:entityManager.mergeentity;entityManager.removeentity;发生了相同的错误!我清理了我的代码示例以使其更具可读性。请再次阅读说明-您不能在实体上调用merge然后删除相同的实体,您必须使用从merge返回的实体。谢谢。现在它可以工作了没错,但是在这个配置中有没有什么方法可以让我不必先合并我的实体来对我的实体执行dao操作?我觉得这不是最佳实践。谢谢。但是我正在尝试类似org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter的东西,但它不起作用:-我不知道为什么?!我正在尝试使用org.springframeworkrk.orm.jpa.support.OpenEntityManagerViewFilter但它对我不起作用。另外,我在某处看到有人说,在视图模式中使用开放数据库连接在性能和内存效率方面并不总是一个好的解决方案。如果是这样,有什么替代方案?听起来像是Spring在妨碍你。最明显的替代方案是你只是不使用它,它是一个不再那么相关的框架。
public void delete(T entity) {
    entityManager.remove(entity);
}
public void delete(T entity) {
    T eT = entityManager.merge(entity);
    entityManager.remove(eT);
}