2 haomingburongyi haomingburongyi 于 2016.02.24 12:34 提问

Hibernate 在同一个事务里执行插入之后懒加载查询问题

这样一段代码:他们是在同一个事务下的

 public class ObjectA{
     private String id;
    private ObjectB objectB;

    ...get/set方法;
}
public void functionA(){
    ObjectA a = new ObjectA();
    dao.add(a);

    functionB(a.getId);

    dao.commit();
}
public void functionB(String id){
    ObjectA pa = dao.get(ObjectA, id);   //根据id查询对象
    ObjectB b = pa.getObjectB();    //这里获取的值为空,但数据库里面是有数据的
}
public void functionA(){
    ObjectA a = new ObjectA();
    a.setObjectB(dao.get(ObjectB.class, id)); //将ObjectB查询出来,set到ObjectA中
    dao.add(a);

    functionB(a.getId);

    dao.commit();
}
public void functionB(String id){
    ObjectA pa = dao.get(ObjectA, id);   //根据id查询对象
    ObjectB b = pa.getObjectB();    //这样就没问题了
}

ObjectA和ObjectB是多对一的关系,配置如下

<many-to-one name="objectB"
            class="com.*.*.ObjectB" insert="false" update="false">
            <column name="objectB_id" length="32" />
</many-to-one>

请大神解释下这是为什么?谢谢!!!

2个回答

haomingburongyi
haomingburongyi   2016.02.24 12:38

我猜测是,在事务没提交的情况下,hibernate无法获取到新增的实体的关联关系,所以懒加载无法使用。这种情况下需要我们手动设置关联关系(将关联的对象赋值给新增的实体)

xionglangs
xionglangs   Rxr 2016.02.24 16:47

这可能是因为懒加载它并没有执行sql,所以这时候数据是空,只有在用的时候才执行,而它的加载周期是在session没有关闭的时候http://selvemen.iteye.com/blog/457225,也就是在commit()方法之前执行的查询才能查询到数据,其余的查询不到数据。
在来看你这里的情况:
第一种情况ObjectA pa = dao.get(ObjectA, id);已经commit了,也就是session已经关闭了,ObjectB b = pa.getObjectB(); 你这里真正查询已经不能执行sql了,所以查出来的是空。
第二种情况 ObjectA pa = dao.get(ObjectA, id);查询 a.setObjectB(dao.get(ObjectB.class, id)); 在commit之前已经用到了查询,且你把查询的数据存入了对象里面,这些数据就成了持久化数据了,这样当然就有数据了。
你也可以把懒加载改成立即加载,这样也会有数据,至于怎么改,到网上搜索下就可以了。

xionglangs
xionglangs 没啥
接近 2 年之前 回复
haomingburongyi
haomingburongyi 第一种情况:session是没关闭的,因为functionA,functionB是在同一事务下的。第二种情况:其实在第一种情况的时候,也是执行过dao.get(ObjetcB.class, id)的。只是我没写出来,不好意思。感谢您的分析
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片