Spring Boot和Spring数据:Hibernate Sessions是如何管理的?

Ala*_*n47 42 session hibernate jpa spring-data spring-boot

我目前正在开发一个使用Spring Boot和Spring Data(它的JpaRepository接口准确)和Hibernate的应用程序.

我喜欢Hiberante的一个方面是它的缓存功能 - 当你提交与特定对象匹配的多个查询时,你将在每次查询执行时返回该对象的相同实例(相对于Java的==运算符).但是,在使用Spring Data和JpaRepository类时,情况似乎并非总是如此.出于这个原因,我假设这里有多个HibernateSession实例在工作.

因此我的问题是:Spring Data如何处理Hibernate会话?什么时候打开或关闭它们?有没有办法将它配置为对我的应用程序的整个运行时使用相同的会话来充分利用Hibernate的对象缓存?有没有理由这样做?

谢谢,

艾伦

Ala*_*n47 57

我想我自己找到了答案.如果有人发现这个问题,这是我的答案.

Spring如何管理Hibernate会话?

默认情况下,Spring Boot在存储库级别应用事务管理.在这种情况下,当调用JpaRepository方法(或通常任何Repository方法)时,Spring将:

  • 要求SessionFactory创建一个新会话
  • 打开此会话
  • 打开一个交易
  • 执行被调用的Repository方法
  • 关闭交易
  • 关闭会话

但是,如果您应用于@Transactional服务类或方法,Spring将在进入服务方法时打开会话和事务,并且将在现有事务中执行存储库方法.

有什么后果?

作为一名程序员......

  • 你根本不需要关心交易或会话.
  • 如果您想依赖Hibernate的缓存功能,则必须@Transactional在比存储库更大的范围上指定.缓存仅适用于同一个HibernateSession.
  • 您必须@Entity通过Hibernate ID值来决定对象的等价性,而不是使用Java的==运算符.
  • 你需要注意@OneToMany你的@Entity类中的惰性集合(例如在引用中)(参见FetchMode.LAZY相反FetchMode.EAGER)仅在一个@Transactional注释方法中使用

另外作为参考,以下链接非常有用:单个会话中的多个事务

与Spring的许多其他方面一样,如果您愿意牺牲对应用程序的直接控制,那么在这里可以获得很多东西.

  • 实际上这不是真的......根据您的事务划分,您将重用已经打开的会话.如果你有一个使用`@Transactional`注释的服务方法(并且已正确设置tx支持),spring将打开一个`Session` /`EntityManager`并重复使用你在该事务中执行的所有db调用.还应注意,您的服务层应该是事务层而不是数据访问层. (9认同)
  • 另请注意,默认情况下,在 Web 应用程序中,Spring Boot 将创建一个 open-entitymanager-in-view,这意味着 Hibernate 会话(位于 EntityManager 后面)持续整个 HTTP 请求处理持续时间。事务仍将在输入 `@Transactional` 方法时创建,但将使用现有的 EntityManager。 (6认同)