繁体   English   中英

Spring + Hibernate:LazyInitializationException

[英]Spring + Hibernate : LazyInitializationException

当我尝试在POJO中检索信息时,出现LazyInitializationException。

User.java

public class User  implements java.io.Serializable {

 private Set groups = new HashSet(0);

    public Set getGroups() {
       return this.groups;
   }

}

UserController.java

@RequestMapping(value = "/home", method = RequestMethod.GET)
public ModelAndView getHome(HttpServletRequest request) throws Exception {
    ModelAndView mv;
    User user = SessionUtil.getSessionUser(request);
    if (user == null) {
        mv = new ModelAndView("redirect:/user/login");
    } else {
        mv = new ModelAndView("home");
        user = this.userService.getUserById(user.getId());

        // Exception here 
        Set<Group> groups = user.getGroups();
        mv.addObject("groups", groups);

        // This work fine
        List<Group> invitation_groups = this.userService.getInvitationGroups(user);
        mv.addObject("invitation_groups", invitation_groups);

        // This work fine
        List<Group> subscription_groups = this.userService.getSubscriptionGroups(user);
        mv.addObject("subscription_groups", subscription_groups);

    }

    return mv;
}

数据库

=====
-用户-
ID
登录

=====
-Goup-
ID
用户(用户外键)


at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at model.pojo.User_$$_jvst464_2.getGroups(User_$$_jvst464_2.java)
at controller.UserController.getHome(UserController.java:151)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

我想我理解为什么会收到此异常:我总是在DAO中完成所有事务后关闭HibernateSession,因此无法为POJO请求打开该会话。

另一方面,user.getLogin()用于示例工作。 我想我不太了解问题所在。 那是因为它使用外键吗?

我想我在这里找到了解决方法但是我不知道如何实现它以及它是否真的有效。

我知道,如果我从DAO中删除session.close(),它将起作用,但这不是解决方案。

我希望有一个人可以帮助我。 谢谢。

  1. 删除所有手工交易
  2. 添加事务处理注释
  3. 用户OpenSessionInView过滤器。

多谢你们。

您为什么要手动处理会话? 你需要那个吗?

如果没有,则应使用OpenSessionInView模式。 它将使您的会话保持打开状态,直到请求结束为止,但是请注意,由于集合的延迟加载,您可能会遇到对数据库进行的许多查询的麻烦。 因此,如果您知道将使用数据,请尝试尽快获取数据。

您的user.getLogin()返回一个字符串对吗? 即使它是关系映射的一侧,默认情况下也会急切地获取它。

我没有用过spring,但我认为spring有一个OpenSessionInView过滤器来管理您的会话。

在API层中使用DTO处理事务是正常的,因此您需要:API-> Service-> DAO。

但是由于您在DAO中仅具有事务性,所以它可能是okai,但是在关闭事务之前,您必须照顾DAO中的lazyload对象。

//在打开和关闭事务之后,您通常会得到用户对象是休眠的jpa实体。
用户= this.userService.getUserById(user.getId());

最简单的解决方案是在返回用户之前,在DAO中遍历并执行getId()。

Set<Group> groups = user.getGroups();

 for (Group group in groups){
   group.getId(); 
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM