![](/img/trans.png)
[英]LazyInitializationException with ModelMapper (Spring + Hibernate)
[英]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(),它将起作用,但这不是解决方案。
我希望有一个人可以帮助我。 谢谢。
多谢你们。
您为什么要手动处理会话? 你需要那个吗?
如果没有,则应使用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.