Struts Spring Hibernate中的惰性初始化Hibernate
我在会话中保存当前用户,当我使用当前用户(例如:user.getRole.getRoleName())时,我得到了谎言。如何解决这个问题,我的代码是这样的Struts Spring Hibernate中的惰性初始化Hibernate,spring,hibernate,struts,Spring,Hibernate,Struts,我在会话中保存当前用户,当我使用当前用户(例如:user.getRole.getRoleName())时,我得到了谎言。如何解决这个问题,我的代码是这样的 @Override public Users getDetailUser(String username) { try { Users user = (Users)sessionFactory.getCurrentSession().createQuery("SELECT U FROM Users U WHERE U.
@Override
public Users getDetailUser(String username) {
try {
Users user = (Users)sessionFactory.getCurrentSession().createQuery("SELECT U FROM Users U WHERE U.username=:USERNAME")
.setParameter("USERNAME", username)
.uniqueResult();
return user;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
控制器:
public String home(){
Users users = userService.getCurrentUser();
if(users.getRole().getRoleName().equals("admin")){ //causing LIE
....
}
用户服务:
@Override
public Users getCurrentUser(){
session = ActionContext.getContext().getSession();
return (Users) session.get("user");
}
但是,当我将userService.getCurrentUser()更改为这样时,错误得到了解决,但我认为这不是一种正确的方式,因为每次我使用当前用户时,它都需要连接到数据库
@Override
public Users getCurrentUser(){
session = ActionContext.getContext().getSession();
return daoManager.getDetailUser(((Users) session.get("user")).getUsername());
}
DaoManager.getDetailUser是这样的
@Override
public Users getDetailUser(String username) {
try {
Users user = (Users)sessionFactory.getCurrentSession().createQuery("SELECT U FROM Users U WHERE U.username=:USERNAME")
.setParameter("USERNAME", username)
.uniqueResult();
return user;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
有没有其他更好的办法来解决这个问题?谢谢。最有可能的解释是,Spring在您退出服务层(
UserService
)时关闭当前会话,但是,在这种情况发生之后,因为Hibernate尝试延迟加载子对象以避免不必要地加载数据(另请参阅)
为了避免这种情况,您可以通过在
角色
上指定fetch=FetchType.EAGER
来确保hibernate不进行延迟加载,或者使用该模式(不过,有时这被视为反模式,请参阅).解决此问题的最简单方法是在会话关闭之前访问延迟获取字段:
@Override
public Users getCurrentUser(){
session = ActionContext.getContext().getSession();
Users user = (Users) session.get("user");
user.getRole(); //Accessed to resolve lazy field
return user;
}
我不推荐FetchType.EAGER。由于您无法控制访问,因此无论您是否需要,都会获取它。。向数据模型中添加几个急切字段,然后突然获取整个数据库以获得最简单的请求
对于查询,您也可以使用
JOIN FETCH
同意您不要使用FetchType.EAGER,因为无论是否需要,都将加载所有数据。关于user.getRole();如果我们需要更深入的数据,例如在其他情况下,我们是否会对每个模型都这样做?我很震惊,最终这将接近FetchType.EAGER。我说的对吗?你应该组织好你的代码,这样你就可以在任何情况下只获取你需要的节点……这是不可行的(get LIE),因为当代码为user.getRole()时,没有打开的会话;执行。还有别的办法吗?