我将当前用户保存在会话中,当我使用当前用户(例如:user.getRole.getRoleName())时,我得到了LIE。我怎么能解决这个问题,我的代码是这样的
控制器:
public String home(){
Users users = userService.getCurrentUser();
if(users.getRole().getRoleName().equals("admin")){ //causing LIE
....
}
UserService:
@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;
}
}
还有其他更好的方法来解决这个问题吗?谢谢。
答案 0 :(得分:1)
最可能的解释是Spring在退出服务层(UserService
)时关闭当前会话,但是,在此之后,因为Hibernate试图延迟加载子对象以避免不必要地加载数据(另见What is lazy loading in Hibernate?)。
要避免这种情况,您可以通过在fetch=FetchType.EAGER
上指定role
来确保hibernate不进行延迟加载,或者使用OpenSessionInView模式(但是,有时会将其视为反模式) ,见Why is Hibernate Open Session in View considered a bad practice?)。
答案 1 :(得分:1)
解决此问题的最简单方法是在会话关闭之前访问延迟获取的字段:
@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。有了它你无法控制访问,无论你是否需要它都会被提取。为你的数据模型添加一些EAGER字段,然后突然你为最简单的请求提取整个数据库..
对于查询,您还可以使用JOIN FETCH