为什么需要实体管理器clear()? - Spring3 @Transactional,JPA2 / Hibernate3

时间:2012-09-10 14:51:28

标签: jpa-2.0 spring-3 transactional hibernate3

我有一个使用JPA2 / Hibernate和Spring @Transactional的JSF2应用程序。 UI(支持bean)中没有@Transactional语句,仅在服务层中。 (我在DAO中使用@Transactional(propagation = Propagation.MANDATORY)来确保每次调用都发生在事务中。)除了......之外,它们都非常好用。

当我通过事务服务方法打开和更新实体时,有时检索到的实体是旧的。在同一个会话中它是同一个用户并不重要,偶尔,JPA“读取”方法会返回已经(应该)已经被替换的旧陈旧实体。这困扰了我很长一段时间,但事实证明它是由实体管理器中的缓存引起的。 DAO使用@Repository注释,因此注入的EntityManager正在重用。我曾预料到,当交易完成后,实体经理将自动被清除。但事实并非如此。通常,实体管理器返回正确的值,但通常会返回并返回先前事务中的旧值。

作为一种解决方法,我在DAO读取方法中添加了战略性的entityManager.clear()语句,但这很难看。每次交易后都应清算entityManagers。

有没有人经历过这个?有适当的解决方案吗?每次交易后,实体经理都可以清算吗?

非常感谢。

我正在使用:org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean和org.springframework.orm.jpa.JpaTransactionManager

2 个答案:

答案 0 :(得分:1)

@Transactional注释存在于服务层中。标记为@Transactional的服务方法将遵循ACID属性,无论从其中进行多少次DAO调用。

这意味着您无需将DAO方法注释为@Transactional。

我正在研究类似的事情,这就是我如何做到这一点,我的数据是一致的。

尝试一下,看看你是否仍然收到不一致的数据。

答案 1 :(得分:0)

您是否使用@PersistenceContext注释(在DAO中的EntityManager之上)与PersistenceAnnotationBeanPostProcessor bean结合使用(如果您使用PersistenceAnnotationBeanPostProcessor并且不需要定义<context:annotation-config/> bean <context:component-scan/> XML标签)?如果没有,我想这就是你遇到问题的原因。