hibernate 懒加载异常分析: failed to lazily initialize a collection of role

初始环境:hibernate 每个用户对应一个小组 。user--group(many to one)。group--user(one to many)  


Group代码片段

[java]  view plain  copy
  1. @OneToMany(mappedBy="group" )  
  2.     @JoinColumn(name="groupid")  
  3.     public Set<User> getUsers() {  
  4.         return users;  
  5.     }  



User代码片段

[java]  view plain  copy
  1. @ManyToOne  
  2.     @JoinColumn(name="groupid")  
  3.     public Group getGroup() {  
  4.         return group;  
  5.     }  



在执行这段代码时

[java]  view plain  copy
  1. @Test  
  2. public void testGetGroup(){  
  3.     //testSaveGroup();  
  4.       
  5.     Session se=sf.getCurrentSession();  
  6.     se.beginTransaction();  
  7.     Group g=(Group)se.get(Group.class1);  
  8.       
  9.     se.getTransaction().commit();  
  10.     for(User u : g.getUsers()){  
  11.         //g.getUsers()   
  12.         System.out.println("------------------");  
  13.         System.out.println(u.getName());  
  14.     }  
  15. }  

会出现异常:

[html]  view plain  copy
  1. 18:26:28,624 ERROR org.hibernate.LazyInitializationException:42 - failed to lazily initialize a collection of role: com.hibernate.crud.Group.users, no session or session was closed  
  2. org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.hibernate.crud.Group.users, no session or session was closed  
  3.     at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)  
  4.     at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)  
  5.     at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)  
  6.     at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)  
  7.     at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)  
  8.     at com.hibernate.crud.test.testGetGroup(test.java:69)  
  9.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  10.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)  
  11.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
  12.     at java.lang.reflect.Method.invoke(Method.java:606)  
  13.     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)  
  14.     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)  
  15.     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)  
  16.     at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)  
  17.     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)  
  18.     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)  
  19.     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)  
  20.     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)  
  21.     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)  
  22.     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)  
  23.     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)  
  24.     at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)  
  25.     at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)  
  26.     at org.junit.runners.ParentRunner.run(ParentRunner.java:236)  
  27.     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)  
  28.     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)  
  29.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)  
  30.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)  
  31.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)  
  32.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)  

也就是懒加载异常
[html]  view plain  copy
  1. failed to lazily initialize a collection of role: com.hibernate.crud.Group.users, no session or session was closed  


经过马士兵老师的讲解,基本了解常形成的原因,现在大致谈一谈,当做个人笔记。

这是因为Hibernate Annotation的默认的FetchType在ManyToOne是EAGER的,在OneToMany上默认的是LAZY.

就是说这段代码中,User是FetchType.EAGER。 而Group是FetchType.LAZY。

具体是因为在这段代码中

[html]  view plain  copy
  1. @Test  
  2.     public void testGetGroup(){  
  3.         //testSaveGroup();  
  4.           
  5.         Session se=sf.getCurrentSession();  
  6.         se.beginTransaction();  
  7.         Group g=(Group)se.get(Group.class, 1);  
  8.           
  9.         se.getTransaction().commit();  
  10.         for(User u : g.getUsers()){  
  11.             //g.getUsers()   
  12.             System.out.println("------------------");  
  13.             System.out.println(u.getName());  
  14.         }  
  15.     }  

执行 
[html]  view plain  copy
  1. Group g=(Group)se.get(Group.class, 1);  
查询到的结果是

[html]  view plain  copy
  1. select group0_.id as id1_0_, group0_.name as name1_0_ from t_group group0_ where group0_.id=?  
只有group表的数据。

而要执行


for(User u : g.getUsers()){    


还需要连接数据库,但是session已经提交关闭了。所以会报 failed to lazily initialize a collection of role 异常。
要解决这个问题
1.可以在Group中设置FetchType.EAGER,得到对应的User表,缓存。如下:<br>  
@OneToMany(mappedBy="group",fetch=FetchType.EAGER )  
    @JoinColumn(name="groupid")  
    public Set<User> getUsers() {  
        return users;  
    }
2.将提交放在最后。如下:
@Test  
    public void testGetGroup(){  
        //testSaveGroup();  
          
        Session se=sf.getCurrentSession();  
        se.beginTransaction();  
        Group g=(Group)se.get(Group.class, 1);  
          
        for(User u : g.getUsers()){  
            //g.getUsers()   
            System.out.println("------------------");  
            System.out.println(u.getName());  
        }  
        se.getTransaction().commit();  
    }  
      
现在正在学习hibernate,以后有其他方法或者错误,会有所更新。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值