我有一个使用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
答案 0 :(得分:1)
@Transactional注释存在于服务层中。标记为@Transactional的服务方法将遵循ACID属性,无论从其中进行多少次DAO调用。
这意味着您无需将DAO方法注释为@Transactional。
我正在研究类似的事情,这就是我如何做到这一点,我的数据是一致的。
尝试一下,看看你是否仍然收到不一致的数据。
答案 1 :(得分:0)
您是否使用@PersistenceContext
注释(在DAO中的EntityManager之上)与PersistenceAnnotationBeanPostProcessor
bean结合使用(如果您使用PersistenceAnnotationBeanPostProcessor
并且不需要定义<context:annotation-config/>
bean <context:component-scan/>
XML标签)?如果没有,我想这就是你遇到问题的原因。