休眠:在session.load的情况下急切和延迟加载vs session.get
我的印象是session.load()
加载缓存中的代理对象,而session.get()
总是碰到数据库,但在观看JavaBrains video后我感到困惑。休眠:在session.load的情况下急切和延迟加载vs session.get
根据这段视频,当我们调用下面的get方法时,它会在内存中加载代理对象UserDetails
。
user = (UserDetails) session.get(UserDetails.class, 1);
的UserDetails
结构
虽然在注释部分,一个家伙说:
没有代理用户类,而不是代理对象 集合已创建。
现在有两个问题在这里。
1st:涉及session.load()和session.get()的取回策略和创建代理对象,这个问题已经由我回答。
第二种:在这种情况下,代理对象将为UserDetails或收集创建(仍有待回答)。
感谢
我得到了答案here
Hibernate默认会创建运行时代理。它将对象加载为代理,除非指定了获取模式或设置为false。 这就是为什么它总是创建一个对象的代理(如果我们使用get()或load()以及任何获取策略)无关紧要。
get()首先在缓存中检查代理是否存在,如果不存在,它将触发数据库,同时在缓存中创建对象的代理并返回代理对象,一旦对象加载到缓存中,随后的下一个调用将执行可重复读取。
load()总是检索代理对象。它从永久上下文缓存中读取数据,并且如果代理不存在于缓存中,它将返回null。
这里,UserDetails
是家长和Address
是孩子。 Hibernate实际上是懒加载儿童Address
。 因此,最终所有的子元素(在这种情况下为Address
)在加载父元素(本例中为UserDetails
)时未预先加载。
所以,当你这样做:
user = (UserDetails) session.get(UserDetails.class, 1);
休眠没有实际加载的所有子(Collection<Address>
)。 而是仅当您明确地访问它们时,Hibernate才会加载Address
。所以休眠不会打DB的Address
表,除非你真的需要它们,这就是延迟加载的目的。
这意味着通过延迟加载是什么,而你得到的UserDetails
代理对象,它并不真正打Address
表,除非您尝试显式访问集合元素。换句话说,您需要遍历集合进行休眠以获取Address
表。
您可能会陷入每次为每个孩子敲击数据库(Address
)的情况。因此,请拨打listOfAddresses.size()
以便一次加载所有的孩子。
还要注意的是延迟加载将默认为发生一到多和许多一对多箱子。
2问题回答: 代理服务器的地址为您的问题上下文,您可以这么说。 深入或详细地说,第一个hibernate也会为userdetail创建代理,但只要查询命中,代理将有数据。但是,由于默认情况下hibernate是延迟加载,而Address是UserDetail中的子代,它将仅作为代理返回,并且您将只获得Address(主键值)的id值。 不要对代理服务器感到困惑。代理将为所有类的父类(UserDetail)或子类(Address)创建,但对于子类,它将只有id数据。
我只想知道谁投下了这个票。你可以解释这里有什么问题。 –
是的,这正是我在评论中提到的。为了测试您的情况,为什么不在代码中尝试'session.clear()'并分析结果? 清除二级缓存,请阅读: https://dzone.com/articles/clearing-hibernate-second-leve –
@Rahul,的确你是对的,如果你能回答第二个问题“在这个问题代理对象将创建UserDetails或收集?“ – Gaurav