【问题标题】:LazyInitializationException with hibernate and spring mvc带有休眠和spring mvc的LazyInitializationException
【发布时间】:2014-12-10 03:34:08
【问题描述】:

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

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;



}

我阅读了很多关于这个问题的信息,但任何解决方案都对我有用;如果您需要更多信息,请告诉我。

【问题讨论】:

    标签: java hibernate spring-mvc


    【解决方案1】:

    您收到此错误是因为集合(在本例中为 Set)在 Hibernate 中默认是延迟加载的。

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

    在您的情况下发生的事情是这样的:您正在向 Hibernate 询问该对象,它会查询它,但没有 Set 集合。然后休眠会话关闭。您的 UI,无论是 JSP、JSF 还是 servlet 或其他什么,然后尝试获取 Person 的“tasks”属性,可能是通过一个表达式,然后调用 getTasks()。因此 Hibernate 尝试对数据库进行第二次调用以获取 Set 集合,但会话已经关闭。因此例外。

    有两种可能的解决方法:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2015-03-13
        • 1970-01-01
        • 2016-09-16
        • 1970-01-01
        • 2016-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多