Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Struts Spring Hibernate中的惰性初始化Hibernate_Spring_Hibernate_Struts - Fatal编程技术网

Struts Spring Hibernate中的惰性初始化Hibernate

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.

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

@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()时,没有打开的会话;执行。还有别的办法吗?