【问题标题】:Why is Entity Manager clear() required? - Spring3 @Transactional, JPA2/Hibernate3为什么需要 Entitymanager clear()? - Spring 3 @Transactional,JPA2/Hibernate 3
【发布时间】:2012-09-10 14:51:27
【问题描述】:

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

【问题讨论】:

    标签: jpa-2.0 spring-3 transactional hibernate3


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我想确保如果在现有事务之外直接调用了 DAO 方法之一,则会引发异常。 DAO 绝不能启动事务。我认为这就是 @Transactional(propagation=Propagation.MANDATORY) 会做的事情。
    • 决不应该直接调用 DAO。服务层访问 DAO 层。控制器/端点应该访问服务层。那么为什么要考虑直接调用 DAO。服务层将调用 DAO。
    • 如果只将@Transactional 添加到DAO,即没有propagation=Propagation.MANDATORY,它的行为是否也一样。
    • 默认传播是必需的,这可能会导致在 DAO 中创建事务。我不想那样做。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2012-04-29
      • 1970-01-01
      • 2018-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-21
      • 2017-07-20
      • 2017-04-22
      相关资源
      最近更新 更多