hibernate - 在 Spring/Hibernate 堆栈中打开 session 的位置?

标签 hibernate spring

我正在尝试为 Spring/Hibernate 应用程序找出一个好的设计。在创建这样的应用程序时,似乎有一些重大决策。

第一个主要决定似乎是在哪里放置 session /事务边界。似乎我有 3 个主要选择:作为甚至调用 Controller 之前的过滤器,在服务调用级别的 Controller 下方,以及在存储库调用中的业务级别下方的填充方式。

在我看来,正确的选择是中间道路,但我不确定。我不希望我的事务打开时间过长,但同时,我也不希望经常担心分离对象和业务逻辑中的延迟加载。不过,也有一些缺点。例如,业务逻辑很难在不暂停事务几秒钟的情况下进行远程调用。我想知道有没有更好的方法?

最佳答案

解决方案 1:在 View 过滤器中打开 session

  • 好处 :
  • 您不会遇到延迟初始化异常,因此您可以在 View 中使用模型对象而无需三思
  • 如果您进行多次服务调用(如果在第二次服务调用期间发生错误,您的第一次调用将不会回滚),您不必担心 Controller 在不同事务中的工作。
  • 缺点 :
  • 更长的交易
  • 如果提交时发生错误(例如违反数据约束),您将已经在响应输出流中写入了大部分 View ,因此您将无法显示错误页面(除非您使用“打开”上方的另一个过滤器 View 中的 session '一个将存储外流直到提交完成,然后才将生成的页面发送到客户端或重定向到错误页面)

  • 方案二:业务层的事务边界
  • 好处 :
  • Controller 级别的灵 active 更高(但如果您的团队成员并不真正了解事务,并且在 Controller 级别放置了太多逻辑,使用多个 tx 而应该只有一个,这可能是一个诅咒)
  • 更少的资源使用(因为您更快地将数据库连接返回到池)
  • 缺点 :
  • 在事务层之外,您需要小心使用模型的对象。避免延迟初始化异常的最简单方法可能是使用 DTO,并让每个服务实现两个接口(interface)(一个扩展另一个接口(interface)):一个只包含返回 DTO 的方法,另一个只包含返回模型对象的方法。您将在 Controller 的声明中使用第一个接口(interface),而仅在业务层中使用第二个接口(interface),其中事务仍处于打开状态,因此返回模型对象不会导致惰性初始化异常。

  • 解决方案 3:dao 层的事务边界

    除非您的 dao 方法包含业务逻辑,否则将事务限制为 dao 调用是没有意义的。我认为这是接近“自动提交”模式有用的方式。

    在任何情况下,如果您希望保持事务简短,我建议您密切关注每个业务用例的“sql 足迹”(通过将 org.hibernate.SQL 日志类别设置为 DEBUG)并将生成的 sql 与什么进行比较你会自己写的。

    大多数时候我看到缓慢的用例,这是因为没有正确配置 hibernate 延迟加载功能(它要么太急,在每个查询中添加 12 级连接,要么太懒,按集合元素发出查询)

    关于hibernate - 在 Spring/Hibernate 堆栈中打开 session 的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2863587/

    相关文章:

    mysql - 如何在 hibernate 状态下检查连接

    java - 使用 Spring Data MongoDB 时,使用 Map 作为 bean 中的属性时出现异常?

    java - 与执行者共享ApplicationContext

    java - Spring:如何通过 XML 将属性值注入(inject)到 bean 中?

    java - Spring Boot 中的 CrudRespository 方法在哪里实现?

    java - Hibernate - 用户及其报告列表

    java - 保存从Entity扩展的实例

    java - 异常(exception):实体映射中的重复列:列:哈希(应使用 insert ="false"update ="false"进行映射)

    java - org.hibernate.MappingException : Foreign key (FK12A711396456CA10:) must have same number of columns as the referenced primary key

    java - 在 Spring 中创建 worker