如果从数据库加载两次,hibernate 是否会加载同一实例的两个单独副本?

2024-03-07

我知道关于延迟加载有很多不同的问题,但我的问题有点不同。

假设我有一个实体 A,其中有实体 B 的集合。类似地,在实体 B 中,我有 A 的集合。在这两种情况下,都使用lazy="true" 选项。

Entity A的实例 aA 有 -->Set<B>===(该集合包含实体B的实例bB)

Entity B的实例 bB 有 -->Set<A>===(该集合包含实体A的实例aA)

现在,如果我加载实体 A 的集合(即Set<B>).现在已经初始化了,即完成A的aA实例,包括集合。我现在期望的是实体 B 的实例 bB 也已完全初始化,但不,它没有,当我引用实体 B 的包含实体 A 的实例 aA 的集合时,我会遇到延迟初始化异常。

如果从数据库加载两次,hibernate 是否会加载同一实例的两个单独副本?如果是这样,有没有办法同步会话内所有副本中的更改?

希望我足够清楚并且没有因为混乱的信息而搞砸事情:)


如果从数据库加载两次,hibernate 是否会加载同一实例的两个单独副本?

不,它不会在同一个会话中两次加载同一个对象(为了我们的理智)。

我创建了一个简单的Spring Boot 项目 https://github.com/gabrielgiussi/so-31045875/tree/1.2看到这个。

EntityA#setOfB(B1,B2)
EntityB#setOfA(A1)

通过 ID 将 EntityA 1 和 EntityB 加载到 Session 后,我们强制 A1.setOfB 初始化。 在下面的日志中我们可以看到,虽然它必须查询集合以获得两行(B1和B2),但它只会隐藏一个对象(B2),因为B1是在会话缓存中找到的。请参阅测试 1 (mvn spring-boot:run -Drun.arguments="1")

DEBUG 6452 --- [           main] o.g.hiplay.app.HibernateService          : ########## Retrieving A1's set of B ##########
DEBUG 6452 --- [           main] org.hibernate.SQL                        : select setofb0_.id_a as id_a1_0_0_, setofb0_.id_b as id_b2_2_0_, entityb1_.id as id1_1_1_, entityb1_.description as descript2_1_1_ from relations setofb0_ inner join entityb entityb1_ on setofb0_.id_b=entityb1_.id where setofb0_.id_a=?
TRACE 6452 --- [           main] o.h.l.p.e.i.AbstractLoadPlanBasedLoader  : Bound [2] parameters total
DEBUG 6452 --- [           main] o.h.l.p.e.p.i.ResultSetProcessorImpl     : Preparing collection intializer : [oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]
TRACE 6452 --- [           main] o.h.e.loading.internal.LoadContexts      : Constructing collection load context for result set [rs3: org.h2.result.LocalResult@5c99abd7 columns: 4 rows: 2 pos: -1]
TRACE 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : Starting attempt to find loading collection [[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]]
TRACE 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : Collection not yet initialized; initializing
TRACE 6452 --- [           main] o.h.l.p.e.p.i.ResultSetProcessorImpl     : Processing result set
DEBUG 6452 --- [           main] o.h.l.p.e.p.i.ResultSetProcessorImpl     : Starting ResultSet row #0
DEBUG 6452 --- [           main] e.p.i.CollectionReferenceInitializerImpl : Found row of collection: [oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]
TRACE 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : Starting attempt to find loading collection [[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]]
TRACE 6452 --- [           main] o.h.e.loading.internal.LoadContexts      : Attempting to locate loading collection entry [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] in any result-set context
TRACE 6452 --- [           main] o.h.e.loading.internal.LoadContexts      : Collection [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] located in load context
TRACE 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : Found loading collection bound to current result set processing; reading row
TRACE 6452 --- [           main] o.h.e.internal.DefaultLoadEventListener  : Loading entity: [oss.gabrielgiussi.hiplay.entities.EntityB#1]
TRACE 6452 --- [           main] o.h.e.internal.DefaultLoadEventListener  : Attempting to resolve: [oss.gabrielgiussi.hiplay.entities.EntityB#1]
TRACE 6452 --- [           main] o.h.e.internal.DefaultLoadEventListener  : Resolved object in session cache: [oss.gabrielgiussi.hiplay.entities.EntityB#1]
DEBUG 6452 --- [           main] o.h.l.p.e.p.i.ResultSetProcessorImpl     : Starting ResultSet row #1
TRACE 6452 --- [           main] l.p.e.p.i.EntityReferenceInitializerImpl : hydrating entity state
TRACE 6452 --- [           main] l.p.e.p.i.EntityReferenceInitializerImpl : Initializing object from ResultSet: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [           main] o.h.p.entity.AbstractEntityPersister     : Hydrating entity: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
DEBUG 6452 --- [           main] e.p.i.CollectionReferenceInitializerImpl : Found row of collection: [oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]
TRACE 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : Starting attempt to find loading collection [[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]]
TRACE 6452 --- [           main] o.h.e.loading.internal.LoadContexts      : Attempting to locate loading collection entry [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] in any result-set context
TRACE 6452 --- [           main] o.h.e.loading.internal.LoadContexts      : Collection [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] located in load context
TRACE 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : Found loading collection bound to current result set processing; reading row
TRACE 6452 --- [           main] o.h.e.internal.DefaultLoadEventListener  : Loading entity: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [           main] o.h.e.internal.DefaultLoadEventListener  : Attempting to resolve: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [           main] o.h.e.internal.DefaultLoadEventListener  : Resolved object in session cache: [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [           main] o.h.l.p.e.p.i.ResultSetProcessorImpl     : Done processing result set (2 rows)
TRACE 6452 --- [           main] o.h.l.p.e.p.internal.AbstractRowReader   : Total objects hydrated: 1
DEBUG 6452 --- [           main] o.h.engine.internal.TwoPhaseLoad         : Resolving associations for [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [           main] o.h.e.loading.internal.LoadContexts      : Attempting to locate loading collection entry [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityB.setOfA#2]] in any result-set context
TRACE 6452 --- [           main] o.h.e.loading.internal.LoadContexts      : Collection [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityB.setOfA#2]] not located in load context
TRACE 6452 --- [           main] org.hibernate.type.CollectionType        : Created collection wrapper: [oss.gabrielgiussi.hiplay.entities.EntityB.setOfA#2]
DEBUG 6452 --- [           main] o.h.engine.internal.TwoPhaseLoad         : Done materializing entity [oss.gabrielgiussi.hiplay.entities.EntityB#2]
TRACE 6452 --- [           main] o.h.e.loading.internal.LoadContexts      : Attempting to locate loading collection entry [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] in any result-set context
TRACE 6452 --- [           main] o.h.e.loading.internal.LoadContexts      : Collection [CollectionKey[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]] located in load context
TRACE 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : Removing collection load entry [org.hibernate.engine.loading.internal.LoadingCollectionEntry<rs=rs3: org.h2.result.LocalResult@5c99abd7 columns: 4 rows: 2 pos: 2, coll=[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]>@131c8e88]
DEBUG 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : 1 collections were found in result set for role: oss.gabrielgiussi.hiplay.entities.EntityA.setOfB
TRACE 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : Ending loading collection [org.hibernate.engine.loading.internal.LoadingCollectionEntry<rs=rs3: org.h2.result.LocalResult@5c99abd7 columns: 4 rows: 2 pos: 2, coll=[oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]>@131c8e88]
DEBUG 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : Collection fully initialized: [oss.gabrielgiussi.hiplay.entities.EntityA.setOfB#1]
DEBUG 6452 --- [           main] o.h.e.l.internal.CollectionLoadContext   : 1 collections initialized for role: oss.gabrielgiussi.hiplay.entities.EntityA.setOfB
TRACE 6452 --- [           main] o.h.e.i.StatefulPersistenceContext       : Initializing non-lazy collections
DEBUG 6452 --- [           main] o.g.hiplay.app.HibernateService          : ########## The object hasn't been loaded twice ##########

Hibernate 检查是否补水对象 https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/loader/Loader.java#L1542已经在会话缓存中询问 StatefulPersistenceContext https://github.com/hibernate/hibernate-orm/blob/5.0/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java#L598

我现在期望的是实体 B 的实例 bB 也已完全初始化,但不,它没有,当我引用实体 B 的包含实体 A 的实例 aA 的集合时,我会遇到延迟初始化异常。

真正未初始化的是 bB 的 A 集。在执行以下操作后:

EntityA aA = session.get("A",a) aA.setOfB.size() // 强制初始化惰性集合。此时 bB 已被水合并放入内存中,但他的 A 集合尚未初始化。

如果您尝试访问集合的元素,Hibernate 需要初始化该集合(到目前为止,它所拥有的只是一个代理,具有在需要时从数据库加载集合的智能,例如询问元素或集合的大小) 。请参阅测试 3 (mvn spring-boot:run -Drun.arguments="2")

// outside of the transaction
EntityB bB = aA.setOfB().get(0)
bB.setOfA().size() // LazyInitializationExample

如果您处于事务内部,则集合将被初始化,并且将再次从基中检索与 aA 对应的行,但它不会被水化。请参阅测试 3 (mvn spring-boot:run -Drun.arguments="3")

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果从数据库加载两次,hibernate 是否会加载同一实例的两个单独副本? 的相关文章

  • org.springframework.validation.BeanPropertyBindingResult异常

    嗨 我是 spring 框架的新手 我做了一个小例子 我尝试使用 spring 验证 api 验证我的输入字段 这是代码 RequestMapping value applicationFormSubmit method RequestMe
  • Java中反射是如何实现的?

    Java 7 语言规范很早就指出 本规范没有详细描述反射 我只是想知道 反射在Java中是如何实现的 我不是问它是如何使用的 我知道可能没有我正在寻找的具体答案 但任何信息将不胜感激 我在 Stackoverflow 上发现了这个 关于 C
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • JAXb、Hibernate 和 beans

    目前我正在开发一个使用 Spring Web 服务 hibernate 和 JAXb 的项目 1 我已经使用IDE hibernate代码生成 生成了hibernate bean 2 另外 我已经使用maven编译器生成了jaxb bean
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • Spark 1.3.1 上的 Apache Phoenix(4.3.1 和 4.4.0-HBase-0.98)ClassNotFoundException

    我正在尝试通过 Spark 连接到 Phoenix 并且在通过 JDBC 驱动程序打开连接时不断收到以下异常 为简洁起见 下面是完整的堆栈跟踪 Caused by java lang ClassNotFoundException org a
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • getResourceAsStream() 可以找到 jar 文件之外的文件吗?

    我正在开发一个应用程序 该应用程序使用一个加载配置文件的库 InputStream in getClass getResourceAsStream resource 然后我的应用程序打包在一个 jar文件 如果resource是在里面 ja
  • 如何在 javadoc 中使用“<”和“>”而不进行格式化?

    如果我写
  • AWS 无法从 START_OBJECT 中反序列化 java.lang.String 实例

    我创建了一个 Lambda 函数 我想在 API 网关的帮助下通过 URL 访问它 我已经把一切都设置好了 我还创建了一个application jsonAPI Gateway 中的正文映射模板如下所示 input input params
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 如何在桌面浏览器上使用 webdriver 移动网络

    我正在使用 selenium webdriver 进行 AUT 被测应用程序 的功能测试自动化 AUT 是响应式网络 我几乎完成了桌面浏览器的不同测试用例 现在 相同的测试用例也适用于移动浏览器 因为可以从移动浏览器访问 AUT 由于它是响
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List

随机推荐