Grails GORM: could not initialize proxy - no Sessi

2019-04-05 13:10发布

问题:

I have a method with the following structure:

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

The exception I'm getting here is org.hibernate.LazyInitializationException: could not initialize proxy - no Session in the second part of my code. Here the userStatus field is a reference to a different domain class.

I tried to add it.refresh() and Hibernate.initialize(it)to the code before properties are checked, but no use. What am I doing wrong here?

upd: I tried to call the it.attach method before the properties are checked, but right after the method call the value of it.attached is false.

回答1:

I don't think you are doing anything 'wrong', it is just that the object got detached from the hibernate session. A couple of things I'd try:

  • attach the object back to the hibernate session like this: object.attach() (http://grails.org/doc/2.2.1/ref/Domain%20Classes/attach.html)
  • make the association between the two domain classes non-lazy (http://grails.org/doc/2.2.x/ref/Database%20Mapping/lazy.html)


回答2:

I had the same exact error when I was using sub domain classes into one class, if your data size is more than a page size, you would get the error "Message: could not initialize proxy - no Session"

By using <> lazy:false, hibernate will use the session attachment properly and will get the appropriate data displayed.

Thank you for this post. I was able to resolve my error.



回答3:

Thomas Farvour pointed in the right direction. The docs, 13.1.1 Transactions Rollback and the Session, suggest eager-fetching the children as the optimal solution.