1

我有一个使用 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

4

2 回答 2

1

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

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

我正在做类似的事情,这就是我的做法,我的数据是一致的。

试试这个,看看你是否仍然得到不一致的数据。

于 2012-09-11T19:47:25.057 回答
0

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

于 2014-08-20T13:16:48.603 回答