この問題には、Grailsインスタンス内でのGroovyコンソールの作成が関係していると思います。通常のドメインオブジェクトクエリは正常に機能しますが、自己参照型の1対1でクエリを実行しようとすると問題が発生します。
私は次のようなドメインクラスを持っています:
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
--------------------------
コンソール内で、2つのクエリを繰り返そうとすると、例外がスローされます。
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)