org.hibernate.LazyInitializationException错误解决
做的一个小项目里面需要根据不同的角色显示不同的菜单,于是将数据库设计为如下形式:
用户表Admin(id, user_name, role_id)
角色表Role(id, name)
菜单表Menu(id, name, url)
角色菜单表RoleMenu(id, role_id, menu_id)
其中用户表和角色表存在一对一关联,角色表和菜单表存在着多对多关联。系统采用了Hibernate框架,各实体定义如下:
public class Admin implements Serializable{
public Integer id;
public Role role;
…
@OneToOne
@JoinColumn(name=”role_id”)
public Role getRole(){
return this.getRole();
}
}
public class Role implements Serializable{
public Integer id;
public Set<Menu> menus;
…
@ManyToMany
@JoinTable(name=”role_menu” joinColumns= {@JoinColumn(name="role_id")},
inverseJoinColumns={@JoinColumn(name="menu_id")})
public Set<Menu> getMenus(){
return menus;
}
}
用户登录采用ajax实现,登录成功后跳转到IndexAction动态地读取菜单信息,代码如下:
public Map<String, List<Menu>> findUserMenus(Admin admin) {
// TODO Auto-generated method stub
Set<Menu>menus = admin.getRole().getMenus();
Map<String,List<Menu>> map = new HashMap<String, List<Menu>>();
for(Menu menu : menus){
Stringid = menu.getId();
if(id.length() > 2){
StringparentId = id.substring(0, 2);
MenuparentMenu = menuDao.queryById(parentId);
Stringtext = parentMenu.getText();
List<Menu>lstMenu = (List<Menu>)map.get(text);
if(lstMenu == null){
lstMenu= newArrayList<Menu>();
}
lstMenu.add(menu);
map.put(text,lstMenu);
}
}
return map;
}
但登录成功后出现如下错误:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:cn.edu.qfnu.main.model.Role.menus, could not initialize proxy - no Session。
若将Role实体中menus的fetch类型改为EAGER则没有错。在web.xml中已经配置了OpenSessionInViewFilter。折腾了很久才解决。原来OpenSessionInViewFilter用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定,也就是说,在一次请求过程中,Hibernate Session是不会关闭的,懒加载也因此能用。
我的问题是,在登录请求后又发送了一次请求,此时通过session中保存的admin对象获取menus对象的Session已经关闭,因此会出现上述错误。
记录下来,避免以后再犯类似的错误。
转载于:https://blog.51cto.com/js321/1224555
推荐阅读