0

我将当前用户保存在会话中,当我使用当前用户(例如:user.getRole.getRoleName())时,我得到了 LIE。我该如何解决这个问题,我的代码是这样的

控制器:

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

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

4

2 回答 2

1

The most likely explanation will be that Spring closes the current session when you are exiting the service layer (UserService), however, after this happens, because Hibernate attempts to lazily load the children objects to avoid unnecessarily loading data (see also What is lazy loading in Hibernate?).

To avoid this, you could either ensure that hibernate does not do lazy loading by specifying fetch=FetchType.EAGER on the role, or use the OpenSessionInView pattern (however, that's sometimes considered an antipattern, see Why is Hibernate Open Session in View considered a bad practice?).

于 2012-04-10T08:50:39.807 回答
1

The easiest way to resolve this is just to access the lazy fetched field before the session is closed:

@Override
public Users getCurrentUser(){
    session =  ActionContext.getContext().getSession();
    Users user = (Users) session.get("user");
    user.getRole(); //Accessed to resolve lazy field
    return user;
}

I do not recommend FetchType.EAGER. With that you cannot control access, it is always fetched whether you need it or not.. Add a few EAGER fields to your data model and suddenly your fetching the entire database for the simplest requests..

For queries you can also use JOIN FETCH

于 2012-04-10T09:51:13.743 回答