2 baidu 28028901 baidu_28028901 于 2016.02.06 22:26 提问

问一个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)

1个回答

caozhy
caozhy   Ds   Rxr 2016.02.06 22:29

List list = pageDaoImp.findEntityByHQL(hql, id);
它的实现在哪里。这里是懒惰加载的。换一句话说,它其实没有加载page对象,你在里面关闭了 session,导致你关联属性加载不了。

baidu_28028901
baidu_28028901 加载了 这句话实现了 我在这个方法用spring配置了事务
接近 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!