12

我有一个具有以下结构的方法:

public void run(){
    ... 
    for (...) { //this part works correct

        User.withTransaction {
            User user = User.findByUsername(...);

            Position pos = Position.findByName(...)
            if(pos){ ...
            } else { ...
                try{
                    pos.save(flush:true);
                    user.position = pos;
                } catch (Exception e){ ... }
            }
            ...
            try{
                user.save(flush:true, failOnError: true);
            } catch (Exception e){ ... }
        }
    }
    //this part doesn't work
    User.findAll().each {
    ...
        if (...){
            User.withTransaction{
                ...
                //here the operation fails with 
                //org.hibernate.LazyInitializationException: 
                //could not initialize proxy - no Session
                if (!userDetailsMap.containsKey(it.username) 
                         && it.userStatus != blocked){
                    it.userStatus = blocked
                    it.save(flush:true) 
                }
            }
        }
    }
}

我在这里遇到的例外是org.hibernate.LazyInitializationException: could not initialize proxy - no Session在我的代码的第二部分。这里的userStatus字段是对不同域类的引用。

在检查属性之前,我尝试将it.refresh()和添加到代码中,但没有用。Hibernate.initialize(it)我在这里做错了什么?

upd:我尝试it.attach在检查属性之前调用该方法,但在方法调用之后的值为it.attachedis false

4

3 回答 3

20

我认为您没有做任何“错误”的事情,只是该对象与休眠会话分离。我会尝试几件事:

于 2013-04-11T11:32:58.523 回答
0

当我将子域类用于一个类时,我遇到了同样的错误,如果您的数据大小超过页面大小,您将收到错误“消息:无法初始化代理 - 无会话”

通过使用 <>lazy:false,hibernate 将正确使用会话附件并显示适当的数据。

感谢您对这篇文章。我能够解决我的错误。

于 2014-09-20T15:20:55.463 回答
0

Thomas Farvour 指出了正确的方向。文档 13.1.1 Transactions Rollback and the Session 建议使用 Eager-fetching 作为最佳解决方案。

于 2017-03-07T16:05:47.537 回答