poster214
poster214
2010-03-24 10:38
浏览 352
已采纳

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的时候数据就又丢失了,请问这样的问题该怎么解决,这种情况只有个别类会遇到,完全一样的写法有些类就没问题

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

18条回答 默认 最新

  • hujunfei
    hujunfei 2010-03-27 16:33
    已采纳

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

    点赞 评论
  • wanghaolovezlq
    wanghaolovezlq 2010-03-24 10:45

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

    点赞 评论
  • wanghaolovezlq
    wanghaolovezlq 2010-03-24 11:01

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

    点赞 评论
  • pysky521
    pysky521 2010-03-24 11:07

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

    点赞 评论
  • wanghaolovezlq
    wanghaolovezlq 2010-03-24 11:11

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

    点赞 评论
  • wanghaolovezlq
    wanghaolovezlq 2010-03-24 11:50

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

    你这样处理一样应该可以

    Hibernate.initialize(h.getPatient());

    点赞 评论
  • giu567
    giu567 2010-03-25 11:00

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

    点赞 评论
  • iteye_5117
    iteye_5117 2010-03-25 16:56

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

    点赞 评论
  • zybzhen
    zybzhen 2010-03-25 21:02

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

    点赞 评论
  • luoqi0597
    一只_青蛙 2010-03-25 22:14

    使用spring的opensesioninview拦截器

    点赞 评论
  • sdyth3
    sdyth3 2010-03-26 15:15

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

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

    点赞 评论
  • hujunfei
    hujunfei 2010-03-27 15:29

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

    点赞 评论
  • moon_simple
    moon_simple 2010-03-27 22:07

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

    点赞 评论
  • hama_ye
    hama_ye 2010-03-31 17:47

    请用OpenSessionInView, 保持session一直存在

    点赞 评论
  • zbzhangzi
    zbzhangzi 2010-04-01 09:16

    [code="xml"]


    hibernateFilter

    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter





    hibernateFilter

    /*


    [/code]

    试试

    点赞 评论
  • zxlu1986
    zxlu1986 2010-04-01 14:18

    web.xml里增加这个过滤器


    hibernateFilter

    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter





       hibernateFilter

    /*

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

    点赞 评论
  • iteye_11404
    iteye_11404 2010-04-02 01:18



    hibernateFilter

    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter





       hibernateFilter

    /*

    图片也开session

    点赞 评论
  • iteye_16378
    iteye_16378 2010-04-02 10:07

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

    点赞 评论

相关推荐