使用hibernate和spring mvc的LazyInitializationException

时间:2014-12-10 03:34:08

标签: java hibernate spring-mvc

我需要帮助才能找到解决此错误的方法:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.example.myproject.domains.Person.tasks, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
at org.hibernate.collection.internal.PersistentSet.isEmpty(PersistentSet.java:166)
at com.lyncode.jtwig.content.model.compilable.For$Compiled.handleCollection(For.java:132)
at com.lyncode.jtwig.content.model.compilable.For$Compiled.render(For.java:98)
at com.lyncode.jtwig.content.model.compilable.Sequence$Compiled.render(Sequence.java:80)
at com.lyncode.jtwig.content.model.renderable.Replacement.render(Replacement.java:32)
at com.lyncode.jtwig.content.model.compilable.Sequence$Compiled.render(Sequence.java:80)
at com.lyncode.jtwig.parser.JtwigParser$CompiledDocument.render(JtwigParser.java:67)
at com.lyncode.jtwig.parser.JtwigParser$CompiledDocument.render(JtwigParser.java:67)
at com.lyncode.jtwig.mvc.JtwigView.renderMergedTemplateModel(JtwigView.java:102)
at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
...

当我尝试输入到http://localhost:8080/myproject/persons/1

时,服务器会抛出此异常

控制器是:

@RequestMapping("/persons/{id}")
public ModelAndView updateMemeber(@PathVariable Integer id) {

    ModelAndView mav = new ModelAndView("user/show");

    mav.addObject("title", "Show User");
    mav.addObject("person", personService.get(id));
    return mav;

}

并且模型定义如下:

人物模型:

@Entity
@Table(name="persons")
public class Person {

    /**
     * The rest of attributes.
     *
     */

    @OneToMany(fetch = FetchType.LAZY, mappedBy="person")
    public Set<Task> tasks;

    /**
     * get a set of tasks
     */
    public Set<Task> getTasks() {
        return this.tasks;
    }


}

任务模型:

@Entity
@Table(name="tasks")
public class Task {

    /**
       * get a set of tasks
       */

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="person_id")
    private Person person;



}

我读了很多关于这个问题但是任何解决方案对我有用;如果你需要更多东西,请告诉我。

2 个答案:

答案 0 :(得分:3)

您收到此错误,因为在Hibernate中,默认情况下,集合(在本例中为Set&lt; Task&gt;)是延迟加载的。

什么是&#34;延迟加载&#34;?这意味着主对象是从数据库加载的,但只有在调用getTasks()的东西需要时才加载该集合。但是,Hibernate会话仍然必须打开才能工作,因为它是对数据库的另一个调用。

在你的情况下发生的事情是这样的:你正在向Hibernate询问该对象,它会查询它但是没有Set&lt; Task&gt;采集。然后Hibernate会话关闭。您的UI,无论是JSP还是JSF或servlet等,都会尝试进入人员的任务&#34;属性,可能通过表达式,而表达式又调用getTasks()。因此,Hibernate尝试对数据库进行第二次调用以获取Set&lt; Task&gt;收集,但会议已经结束。因此例外。

对此有两种可能的解决方法:

  • 添加一个过滤器,使会话保持打开状态,直到完成UI 渲染。看看Spring附带的OpenSessionInViewFilter。
  • 将FetchType更改为&#34; EAGER&#34;用于任务集合。

第一个修复程序将通过您的应用程序处理类似情况,而不管实体如何。第二个修复程序特定于Person实体的这种用法,因此可能没那么有用。

答案 1 :(得分:-1)

我对Spring MVC并不太熟悉,但我知道在JSF中你需要使用@PostConstruct注释正确构造Person.class - 否则Person和Task将无法正确初始化。