【问题标题】:Spring JPA TransactionSpring JPA 事务
【发布时间】:2013-04-10 18:36:10
【问题描述】:

我在 Spring 托管事务中遇到了一些奇怪的行为。这是一个 Spring MVC 应用程序。我将实体直接绑定到 Web 层。我使用以下服务层代码从数据库加载一个持久实体以进行编辑,该代码是从使用@ModelAttribute 注释的方法调用的。

@Transactional(readOnly = true)
@PreAuthorize("#id == authentication.principal.id or hasRole('ROLE_ADMIN')")
public User findById(Long id) {
    return repository.findOne(id);
}

提交表单时,数据将绑定到此分离实体。作为验证的一部分,我查询数据库以验证为用户指定的电子邮件地址是唯一的。

@Transactional(readOnly = true)
public boolean isEmailAddressUnique(String emailAddress, Long userId){
    return repository.checkEmailAddressUnique(emailAddress, userId) == 0;
}

此时,在执行此查询之前,Hibernate 会尝试刷新之前加载的我不理解的分离实体。如果电子邮件地址不是唯一的,显然这会导致异常。

我正在使用 OpenEntityManagerinViewFilter,但是我希望这应该将 FlushMode 设置为 NEVER,也许不会。

如果我从 isEmailAddressUnique() 中删除 @Transactional 属性,则不会发生刷新,并且一切都按预期工作,我想这可以解决问题,但是我想了解这里发生了什么。

有什么建议吗?

=============

好的,我已经进一步调查了。所以我有 OpenEntityManagerInViewFilter 配置了默认值:

场景一。

[1] MVC 控制器在只读事务 T1 中加载用户实体 [2] 实体因 MVC 字段绑定而被修改 [3] 第二个事务在只读事务 T2 中针对用户表运行。 [4] Hibernate 刷新 T1 中加载的实体。 [5] Hibernate 发出查询

场景 2。

子类化 OEMIVFilter 以将 FlushMode 设置为提交(默认为自动)。

如上所述,将步骤 [4] 和 [5] 颠倒过来,即。即使 T2 被标记为 readOnly Hibernate 仍然尝试在事务结束时刷新。我可以理解场景 1,因为 readOnly 可能只引用当前事务 T2(并且会在执行 T2 之前尝试同步数据库)。但是我希望在场景 2 中不应该发出 Flush。

【问题讨论】:

  • 考虑到这一点我想这是有道理的,因为每个事务都绑定到同一个 Hibernate 会话,即。绑定到 OEMIV 过滤器的请求。然而,这似乎有点危险,因为更改可以刷新到数据库而无需显式重新附加和保存实体。 OpenSessionViewFilter 允许指定 singleSession false 在我看来,这似乎可以通过将每个事务绑定到自己的会话来解决问题,但是我没有看到 OpenEntityManagerInView 过滤器的类似设置。

标签: spring hibernate jpa transactions


【解决方案1】:

一开始我也遇到了同样的问题。我们还使用 OSIV 过滤器,我们的问题是事务注释上的只读标志没有传播到休眠状态。我们必须确保我们使用正确的事务管理器,更重要的是使用 hibernatevendoradapter。 检查您的配置,如果您无法解决问题,请发布您的持久性和弹簧集成配置。

【讨论】:

  • 嗨,马丁。我不熟悉 HibernateVendorAdapter。您能否提供有关其配置方式和功能的更多信息?谢谢。
  • 是的,马丁。你是对的!问题是我没有为 EMF 指定 JPAVendorAdaptor。没有这个,其他一切似乎都可以正常工作。有趣的是,我从使用 Spring Roo 生成的示例项目中复制了初始 JPA 配置。 Roo 生成的文件未指定适配器,但会自动配置 OEMIV 过滤器。所以我猜任何使用 Roo 引导项目的人都可能会遇到相同的行为。任何,再次感谢。快把我逼疯了。
猜你喜欢
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 2016-10-23
  • 2015-12-17
  • 2011-08-06
  • 2013-05-08
  • 2017-02-11
  • 2020-09-06
相关资源
最近更新 更多