带有hibernate和spring mvc的LazyInitializationException [英] LazyInitializationException with hibernate and spring mvc

查看:147
本文介绍了带有hibernate和spring mvc的LazyInitializationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  org.hibernate.LazyInitializationException:无法懒散地初始化一个错误收集角色:org.example.myproject.domains.Person.tasks,无法初始化代理 - 没有会话
在org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
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(Seq uence.java:80)
at com.lyncode.jtwig.content.model.renderable.Replacement.render(Replacement.java:32)
at com.lyncode.jtwig.content.model.compilable。序列$ 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 =人)
公共类人{b
$ b / **
*其余属性。
*
* /

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

/ **
*获取一组任务
* /
public Set< Task> getTasks(){
返回this.tasks;
}


}

任务模型:

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

/ **
*获取一组任务
* /

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = person_id)
私人人物;



}

这个问题,但任何解决方案为我工作;如果您需要更多的东西,请告诉我们。 解决方案

;,在Hibernate中是默认加载的。



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



你的情况发生了什么:你在问Hibernate的对象,它会查询它,但没有Set< Task>采集。然后Hibernate会话关闭。您的用户界面,无论是JSP,JSF还是servlet或其他类型的用户界面,都会尝试通过表达式来获取Person的tasks属性,然后调用getTasks()。因此,Hibernate尝试再次调用数据库以获取Set< Task>收集,但会议已经结束。因此有例外。



有两种可能的解决方法:


  • 添加一个过滤器保持会话打开,直到UI完成
    渲染。查看Spring附带的OpenSessionInViewFilter。

  • 将任务集合的FetchType更改为EAGER。



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


I need help to find a way to fix this error:

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)
...

the server throws this exception while i trying to enter to: http://localhost:8080/myproject/persons/1

the controller is:

@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;

}

and the models are defined like this:

Person model:

@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;
    }


}

Task model:

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

    /**
       * get a set of tasks
       */

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



}

I read many about this issue but any solution worked for me; if you need something more just let me know.

解决方案

You're getting this error because collections, in this case Set<Task>, are lazy-loaded by default in Hibernate.

What is "lazy-loading"? It means that the main object is loaded from the database, but the collection is only loaded once it's needed by something calling getTasks(), in this case. However, the Hibernate session still has to be open for it to work, because it's another call to the database.

What's happening in your case is this: you're asking Hibernate for the object, and it queries it but does so without the Set<Task> collection. Then the Hibernate session closes. Your UI, whether it's a JSP or JSF or servlet or whatever, then tries to get at the Person's "tasks" property, probably through an expression, which in turn invokes getTasks(). So Hibernate tries to make a second call to the database to get the Set<Task> collection, but the session has already closed. Hence the exception.

There are two possible fixes for this:

  • Add a filter that keeps the session open until the UI is done rendering. Have a look at OpenSessionInViewFilter, which comes with Spring.
  • Change the FetchType to "EAGER" for the tasks collection.

The first fix will handle similar situations through your application regardless of the entity. The second fix is specific to this usage of the Person entity, so might be less useful.

这篇关于带有hibernate和spring mvc的LazyInitializationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆