【问题标题】:Spring Data JPA + Hibernate: how to share Hibernate session among threads?Spring Data JPA + Hibernate:如何在线程之间共享 Hibernate 会话?
【发布时间】:2013-02-01 11:12:59
【问题描述】:

在涉及@Entity 实例的计算中,一个线程A 创建一个新线程B。线程A 持有对该实体的引用并将该引用传递给线程B。

线程 A 负责处理单个 HTTP 请求、在存储库中查找实体并发送 HTTP 响应。
线程 B 负责一些涉及该实体的长时间运行的计算。
问:为什么我选择了两个线程? A:我不想要一个长时间运行的 HTTP 请求-响应周期;相反,我希望有一个快速的 HTTP 请求-响应周期,可以快速向我的用户响应“计算开始”。

从线程 A 访问实体完美无缺。
但是从线程 B 访问实体不起作用:当我尝试访问实体关系(应该从 Hibernate 懒惰地获取数据)时,我得到了异常 org.hibernate.LazyInitializationException: could not initialize proxy - no Session

JPA/Hibernate 会话的范围是否为单个线程 - 即创建该会话的线程(在我的情况下是线程 A,因为这是查询我的存储库以获取实体的线程)? 如果是这种情况,如何让多个线程共享一个 Hibernate 会话,以便我可以从多个线程处理同一个实体?

将我的实体的 relashionship 行为更改为“急切加载”不是一个可行的解决方案。我也在寻找一种对我的域类/实体无干扰的解决方案(例如,我不想在我的域类中使用 PersistenceContextEntityManager 来重新附加分离的实体。

【问题讨论】:

  • 来自休眠文档“它 [session] 并不意味着实现者是线程安全的。相反,每个线程/事务都应该获得自己的”。您需要分离对象并将其重新附加到另一个线程的会话。
  • @bmorris591 那么这是否意味着基本上不可能/不允许从两个或多个线程同时处理 JPA 实体?
  • 不是附件。在分离的一个上,所有与线程/锁定相关的警告都适用。
  • 现在出现以下问题:如何告诉“Spring”/“Spring Data JPA”重新附加我的实体?
  • 看看this

标签: hibernate jpa-2.0 spring-data


【解决方案1】:

根据session 的 Javadocs,会话不打算由多个线程使用。
在同时处理分离的实体之前,您需要使用evict 将对象从线程 A 中的会话中分离出来。请记住,如果您需要尚未从数据库中读取的惰性属性,则会抛出 org.hibernate.LazyInitializationException
完成后,您需要调用 merge 以将实体重新附加到会话,然后保存它或其他。

【讨论】:

  • 我会试试你的建议,然后报告它是如何工作的
猜你喜欢
  • 2019-07-20
  • 2016-06-26
  • 2016-10-15
  • 1970-01-01
  • 2017-07-17
  • 2021-05-22
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多