hibernate对象状态问题

Model top = new Model();

Set s=new HashSet();
Session session=sf.getCurrentSession();
session.beginTransaction();
top=(Model)session.load(Model.class, (long)1);

session.getTransaction().commit();

System.out.println(top.getName());//在这里会报错没session,怎么回事啊?难道load除的对象就一定要在session中

才能用?

后来我又改了下代码
Model top = new Model();

Set s=new HashSet();
Session session=sf.getCurrentSession();
session.beginTransaction();
top=(Model)session.load(Model.class, (long)1);

System.out.println(top.getName());//在session结束前这里打印一下

session.getTransaction().commit();

System.out.println(top.getName());//这次竟然都能打印不报错了,但是别的操作就不行 ,比如我top.getChildren()就还
是报没session,我是在一个表里面建乐树状结构。

求高手给我说下原理啊! 我怎么才能让对象脱离session然后我能够使用

4个回答

hibernate大致三种状态,持久状态,游离状态,普通状态。持久状态的时候,你load的任何对象在调用属性的时候,会重新去查询,所以得有session。只有在普通状态的时候,可以直接调用。你getChildren是个树状结构,肯定有关联对象(数据),此时会重新根据关联关系查询数据库放入children,所以也是得有session才行。

load表明是延迟加载,意思即是当你使用该对象时才会去取值,当你的session提交关闭后,你才调用了top.getName(),这个时候才会使用session去数据库中查找数据,而这时session已经关闭,所以会报错,而当你在session提交前就去getName(),此时session并未关闭,所以会成功查找到数据。而最后你调用了两次getName(),第一次在session提交前,查找成功,而第二次也成功是因为你之前查找成功,数据已经在缓存中了,所以再次成功。所以你可以考虑使用下get方法,这个是即时加载,即在get调用时就向数据库中查找数据,而不是延迟到使用它时才去查找。

[code="java"]

load表明是延迟加载,意思即是当你使用该对象时才会去取值,当你的session提交关闭后,你才调用了top.getName(),这个时候才会使用session去数据库中查找数据,而这时session已经关闭,所以会报错,而当你在session提交前就去getName(),此时session并未关闭,所以会成功查找到数据。而最后你调用了两次getName(),第一次在session提交前,查找成功,而第二次也成功是因为你之前查找成功,数据已经在缓存中了,所以再次成功。所以你可以考虑使用下get方法,这个是即时加载,即在get调用时就向数据库中查找数据,而不是延迟到使用它时才去查找。

很经典~~~~~~~~~你session都commit了,当然在此查找找不到。
[/code]

load是代理对象,使用的是“懒加载”的方式,只用当你使用该对象时,才发sql语句,然后将你的对象放入到内存中,你在使用top对象之前就提交了session,所以找不到session,top.getChildren()返回的应该也是个对象,原理同上!

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问