You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate一对一EAGER关联:代码执行结果及原因解析

代码执行结果及详细原因

先直接给出两段打印的结果:

  1. System.out.println(st1.getAdvisor() == st2.getAdvisor()); → 输出true
  2. System.out.println(st1 == st3); → 输出false

下面分别拆解原因:

为什么第一个比较会返回true?

咱们得结合Hibernate的一级缓存和EAGER加载的特性来看:

  • 你设置了Student和Advisor是Fetch.EAGER的一对一关联,这意味着当Hibernate加载Student实例时,会立刻把关联的Advisor也加载进来,而不是等到调用getAdvisor()的时候才懒加载。
  • 当你调用session.load(Student.class, 23)时,Hibernate会把23号学生和他的导师都存入当前Session的一级缓存(也就是会话级别的缓存,只属于这个Session)。
  • 紧接着加载25号学生时,Hibernate发现这个学生的导师和23号的是同一个——它会先去一级缓存里查有没有这个导师的实例,查到了就直接复用,不会再去数据库查一遍,也不会新建一个Advisor对象。
  • 所以st1.getAdvisor()和st2.getAdvisor()指向的是内存里同一个对象,用==比较内存地址自然返回true。

为什么第二个比较会返回false?

这就涉及到Hibernate一级缓存的作用范围了:

  • 每个Session的一级缓存是完全独立的,Session关闭后,缓存里的对象就变成了游离态(不再被Hibernate管理)。
  • 第一个Session关闭后,st1就成了一个普通的Java对象,和Hibernate没关系了。
  • 当你打开新的Session并加载23号学生时,Hibernate会在新的Session的一级缓存里创建一个全新的Student实例(也就是st3),这个对象和之前的st1在内存里是两个不同的实例,地址不一样,所以==比较返回false。

内容的提问来源于stack exchange,提问作者crowley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:16:13