У меня есть две модели с отношением hasMany
class Puturru implements Serializable {
String name
Set<Fua> fuas
static hasMany = [fuas: Fua]
static constraints = {
fuas(nullable: true)
}
}
И
class Fua {
String name
static constraints = {
}
}
При запуске следующего теста я получаю LazyInitializationException
void "test something"() {
given:
def puturrus
Puturru.withNewSession { session ->
p = Puturru.build()
Fua f
for (int i = 0; i < 10; i++) {
f = Fua.build()
p.addToFuas(f)
}
f.save(failOnError: true, flush: true)
}
when:
Puturru.withNewSession {
puturrus = Puturru.createCriteria().listDistinct {
fetchMode("fuas", FetchMode.JOIN)
}
}
then:
Puturru.withNewSession {
assert puturrus.fuas*.name.size() > 0
}
p.fuas.each { it.delete() }
p.delete()
}
Если я установлю отображение puturrus
static mapping = {
fuas lazy: false
}
Затем извлекаются все элементы, хотя он использует несколько вариантов выбора, в противном случае он использует этот запрос
select ...
from puturru ...
left outer join puturru_fua fuas2_ on this_.id=fuas2_.puturru_fuas_id
Я не могу установить сопоставление в реальном приложении, потому что я не хочу получать все записи во всех случаях. Мне кажется, что я что-то упускаю, чтобы критерии пошли дальше промежуточной таблицы.
Я использую Grails 2.3.6 и спящий режим 3.6.10.8.
Кто-нибудь знает, почему не получают объекты "fuas"?
РЕДАКТИРОВАТЬ 1: Дополнительная информация
Я пытался внести некоторые изменения в домены и проверить, чтобы выяснить, в чем проблема.
После предложения @sudhir я начал играть с объединениями. Я изменил критерии на что-то вроде
puturrus = Puturru.createCriteria().listDistinct {
fuas {
}
}
Затем запрос, сгенерированный gorm и hibernate, был
select ...
from puturru this_
inner join puturru_fua fuas3_ on this_.id=fuas3_.puturru_fuas_id
inner join fua fuas_alias1_ on fuas3_.fua_id=fuas_alias1_.id
На этот раз мы получили все записи, но не их связь с доменами puturrus. Мы компрометируем и помещаем второй запрос только для получения ассоциаций, поэтому на данный момент второй блок сеанса
Puturru.withNewSession {
puturrus = Puturru.createCriteria().listDistinct {
fuas {
}
}
Puturru.createCriteria().listDistinct {
fetchMode("fuas", FetchMode.JOIN)
}
}
Это намного лучше, чем мой предыдущий подход, который перебирал все путаницу и все возражения в сеансе критериев, но я думаю, что он все еще неоптимален, поэтому есть ли способ получить как данные, так и ассоциации в одном запросе ?
select fuas0_.puturru_fuas_id as puturru1_1_0_, fuas0_.fua_id as fua2_0_ from puturru_fua fuas0_ where fuas0_.puturru_fuas_id=?
, а затем элементы будут доступны вне сеанса. - person esauro   schedule 23.03.2015