问题描述
- 问一个hibernate的懒加载的问题
-
1.我定义Survey和Page类,Survey设置Page的集合属性,然后建立双向关联,我故意把集合注解成懒加载...
2.然后我通过这段代码把Page集合重数据库取出
3.然后调用Survey的get方法得到集合,再把Page一个一个放进集合中去
4.然后再外面迭代Survey的page集合抛异常是懒加载
为什么?为什么?为什么?/* *通过survey的id取出survey *(我用spring在这方法上面配置了事务) */ public Survey findByid(int id){ Survey survey = surveyDaoImp.getEntity(id); String hql = "from Page p where p.survey.id=? order by p.id desc"; List<Page> list = pageDaoImp.findEntityByHQL(hql, id); for(Page page : list){ survey.getPages().add(page); } return survey; }
我的测试方法
@Test public void test3(){ BeanFactory a = new ClassPathXmlApplicationContext("beans.xml"); SurveyService s = (SurveyService) a.getBean("surveyService"); Survey survey = s.findByid(40); for(Page page : survey.getPages()){ System.out.println(page.getTitle()+":"+page.getId()); } }
下面是2个javabean
@Entity public class Survey { private int id; private String title="未命名"; private String preText="上一步"; private String nextText="下一步"; private String exitText="退出"; private String doneText="完成"; private Date createTime = new Date(); private Users users; private List<Page> pages = new ArrayList<Page>(); @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getPreText() { return preText; } public void setPreText(String preText) { this.preText = preText; } public String getNextText() { return nextText; } public void setNextText(String nextText) { this.nextText = nextText; } public String getExitText() { return exitText; } public void setExitText(String exitText) { this.exitText = exitText; } public String getDoneText() { return doneText; } public void setDoneText(String doneText) { this.doneText = doneText; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } @ManyToOne @JoinColumn(name="users_id") public Users getUsers() { return users; } public void setUsers(Users users) { this.users = users; } @OneToMany(mappedBy="survey", cascade=CascadeType.ALL) public List<Page> getPages() { return pages; } public void setPages(List<Page> pages) { this.pages = pages; } } @Entity public class Page { private int id; private String title = "未命名"; private String description; private Survey survey; private List<Question> questions = new ArrayList<Question>(); @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @ManyToOne @JoinColumn(name="survey_id") public Survey getSurvey() { return survey; } public void setSurvey(Survey survey) { this.survey = survey; } @OneToMany(mappedBy="page", fetch=FetchType.EAGER) public List<Question> getQuestions() { return questions; } public void setQuestions(List<Question> questions) { this.questions = questions; } }
**这是日志的sql语句** Hibernate: select survey0_.id as id2_1_, survey0_.createTime as createTime2_1_, survey0_.doneText as doneText2_1_, survey0_.exitText as exitText2_1_, survey0_.nextText as nextText2_1_, survey0_.preText as preText2_1_, survey0_.title as title2_1_, survey0_.users_id as users8_2_1_, from Survey survey0_ where survey0_.id=? Hibernate: select page0_.id as id0_, page0_.description as descript2_0_, page0_.survey_id as survey4_0_, page0_.title as title0_ from Page page0_ where page0_.survey_id=? order by page0_.id desc
这是抛出的异常
016-2-6 22:26:24 org.hibernate.LazyInitializationException
严重: failed to lazily initialize a collection of role: zhang.model.Survey.pages, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: zhang.model.Survey.pages, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272)
at MyTest.test3(MyTest.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
解决方案
List list = pageDaoImp.findEntityByHQL(hql, id);
它的实现在哪里。这里是懒惰加载的。换一句话说,它其实没有加载page对象,你在里面关闭了 session,导致你关联属性加载不了。