hibernate 延迟加载异常(无法获取lazy对象)

我在jpa中有两个对象:hospitalization与patient,两个对象之间是多对一双向关联,全部都加上lazy
然后在查询的时候使用left join fetch 来加载patient
service如下:
[code="java"]

    try{

        String sql="select h from Hospitalization as h left join fetch h.patient where h.code=?1";
        Query query=entityManager.createQuery(sql);
        query.setParameter(1, code);
        return (Hospitalization) query.getSingleResult();
    }catch(Exception e){
        e.printStackTrace();
        return null;
    }

[/code]
这样返回的hospitalization这个对象无法获取patient这个属性,报no session异常:
[code="java"]
2010-03-24 10:40:22,343 [main] ERROR org.hibernate.LazyInitializationException:19 - could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:166)
[/code]
如果我在service上面用
[code="java"]
Hospitalization h=(Hospitalization) query.getSingleResult();
// System.out.println(h.getPatient().getPatientName());
return h;
[/code]
这样来写可以get到,但是这样hibernate又从数据库查询了一次,明明在调用left join fetch 这个sql的时候已经搜索出来了patient值(在sqlserver上面执行可以看到)但是他却不会组装成对象关联,返回给client的时候数据就又丢失了,请问这样的问题该怎么解决,这种情况只有个别类会遇到,完全一样的写法有些类就没问题

select h.xx,p.xx from Hospitalization as h left join fetch h.patient p where h.code=?1
p.xx是patient对象的属性值

通过fetch all properties 可以加载所有的属性

你不是在fetch h.patient ,fetch all properties也就相当于把patient 属性得到了

感觉你的语句写的有问题,去看看hibernate 文档上是怎么写这种的,我记的不太清楚了-

对的,这样是已经查询出来了,但你实际去取数据的时候还要依赖hibernate底层的sessoin来取,只不过它先缓存在一级缓存中导致

它依赖session,如果关闭了session就无法从session缓存中取数据了,所以才导致这个异常的抛出

你这样处理一样应该可以

Hibernate.initialize(h.getPatient());

http://www.phome.asia/forum/thread/18131.html ,这里有篇文章关于hibernate延迟加载的,可能对你有帮助……

如果是lazy加载模式的话, 你在session关比以前如果没有真实的在数据库里面查询出来东西的花, 那么有的就是一个代理类,当你真得用到数据里面的内容的时候在到数据库查询,session已经关闭了, 就会出错了! 如果不是延迟加载的话, 那就没有问题了,在数据库里面查询出来就放在缓存里面了,session关闭也可以查看对象数据的

写个过滤器,在过滤器中打开session,传递请求,关闭session

使用spring的opensesioninview拦截器

Hibernate延时加载,其实这个异常写的非常之清楚,就是会话关闭,无法对Hibernate实体进行操作。造成这样的情况有很多,什么书写错误啊,逻辑错误啊。

但就此说一下关于lazy机制:
[url=http://www.phome.asia/forum/thread/18131.html] Hibernate延时加载和机制理解 [/url]

应该是返回页面的时候关闭了session,lz这里只是返回了个对象用Hibernate.initialize(h.getPatient());多一条sql也不会影响性能。
如果要是返回的是个list就把hql的h改为你要的属性名称就ok了。

在项目的实际开发中也是用 Hibernate.initialize(实体对象)?

请用OpenSessionInView, 保持session一直存在

[code="xml"]


hibernateFilter

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter





hibernateFilter

/*


[/code]

试试

web.xml里增加这个过滤器


hibernateFilter

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter





   hibernateFilter

/*

有个地方要注意:这过滤器一定要放在所有过滤器的最上面才行



hibernateFilter

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter





   hibernateFilter

/*

图片也开session

get一下就完事了,进了持久化上下文里就可以用了。还有我觉得楼主用这种查询方式很明显映射有问题,可能楼主要从映射上入手看看哦,不然很可能有其他问题。