我假设问题涉及在 Grails 实例中创建 Groovy 控制台;正常的域对象查询工作正常,但尝试一对一地查询自引用会导致问题。
我有一个域类,如下所示:
package demo
class Foo {
String name
static hasMany = [substitutes: Foo]
static constraints = {
}
}
期间bootstrap
,我创建了一个控制台来检查域对象:
import demo.Foo
import org.springframework.web.context.support.WebApplicationContextUtils
import org.codehaus.groovy.grails.commons.GrailsApplication
import grails.util.GrailsUtil
import groovy.ui.Console
class BootStrap {
def init = { servletContext ->
def one = new Foo([name: 'one'])
def two = new Foo([name: 'two'])
[one,two].each { it.save(failOnError: true, flush: true)}
one.addToSubstitutes(two)
one.save(failOnError: true, flush: true)
def appCtx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
def grailsApp = appCtx.getBean(GrailsApplication.APPLICATION_ID);
Binding b = new Binding();
b.setVariable("ctx", appCtx);
def console = new Console(grailsApp.classLoader, b);
console.run()
Foo.list().each{println it.name}
Foo.list().each{println it.substitutes}
println '--------------------------'
}
def destroy = {
}
}
这将在控制台中打印以下内容:
one
two
[demo.Foo : 2]
null
--------------------------
在控制台中,我尝试重复这两个查询,这会引发异常:
groovy> import demo.Foo
groovy> demo.Foo.list().each{println it.name}
groovy> demo.Foo.list().each{println it.substitutes}
one
two
Exception thrown
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: demo.Foo.substitutes, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1243)
at ConsoleScript2$_run_closure2.doCall(ConsoleScript2:3)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1243)
at ConsoleScript2.run(ConsoleScript2:3)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1243)