2012-04-10 102 views
0

我将当前用户保存在会话中,当我使用当前用户(例如:user.getRole.getRoleName())时,我得到了LIE。我怎样才能解决这个问题,我的代码是这样的懒惰初始化在Struts中的Hibernate Spring Hibernate

控制器:

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; 
    } 
} 

有没有其他更好的办法来解决这个问题?谢谢。

回答

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

+0

同意您不使用FetchType.EAGER,因为所有数据都将被加载,无论它是否需要。 关于user.getRole();如果我们需要更深层的数据,例如在其他情况下,我们是否会为每个模型都做到这一点?我很害怕,最终这将会接近FetchType.EAGER。我对吗? – 2012-04-10 16:36:31

+0

那么你应该组织你的代码,以便你只需要获取在任何情况下你将需要的节点... – barsju 2012-04-10 19:35:41

+0

它不工作(获得LIE),因为在没有打开会话时代码user.getRole();执行。有没有其他方法? – 2012-04-12 09:22:33

1

最有可能的解释是,当你退出服务层(UserService)时,Spring会关闭当前会话,但是在这种情况发生之后,因为Hibernate试图延迟加载子对象以避免不必要的加载数据(另请参阅What is lazy loading in Hibernate?)。

为了避免这种情况,你既可以确保休眠不通过在role指定fetch=FetchType.EAGER做延迟加载,或使用OpenSessionInView模式(然而,这有时被认为是一个反模式,见Why is Hibernate Open Session in View considered a bad practice?)。