Возникает вопрос: как заставить GORM генерировать левые соединения вместо внутренних объединений в этом конкретном примере?
Testbed:
Данные классы A, B и C:
class A{
B someObject
}
class B{
C importantObject
}
class C{
boolean interestingFlag
}
Я хочу перечислить все элементы класса A, которые:
- их объект B.C имеет значение null ИЛИ
- их объект B.C интересное значение Flag ложно
То, что я пробовал до сих пор:
Этот подход дает правильный список A, где B.C имеет значение null (условие 2 закомментировано) ИЛИ правильный список A, где B.C.interestingFlag = false (независимо от того, был ли выведен комментарий или нет). Когда оба условных выражения раскомментированы, он возвращает только список элементов, где A.B.C.interestingFlag = false (A.B.C = null условно игнорируется)
// approach 1 (conditional 1 is ignored)
def result = A.withCriteria{
someObject{
or{
isNull('importantObject') // conditional 1, works well when conditional 2 is commented out
importantObject{
eq('interestingFlag', false) // conditional 2, works well alone, discards conditional 1 when both of them are uncommented
}
}
}
}
Изменить: Как запрошено в комментарии, я вставляю спящий сгенерированный sql:
Hibernate: select this_.id as id1_2_, this_.version as version1_2_,
this_.some_object_id as some3_1_2_, someobject1_.id as id2_0_,
someobject1_.version as version2_0_, someobject1_.important_object_id as
important3_2_0_, importanto2_.id as id0_1_, importanto2_.version as version0_1_,
importanto2_.interesting_flag as interest3_0_1_ from a this_
inner join b someobject1_ on this_.some_object_id=someobject1_.id
inner join c importanto2_ on someobject1_.important_object_id=importanto2_.id
where ((someobject1_.important_object_id is null or (importanto2_.interesting_flag=?)))
Когда я копирую и вставляю его в инструмент запроса pgAdmin непосредственно с некоторыми изменениями (внутренние объединения меняются на левые соединения и предоставляют интересный параметр Flag = "false" ), все работает так, как я хотел (я получаю оба ABC = null и ABCimportantFlag = ложные объекты)
Hibernate: select this_.id as id1_2_, this_.version as version1_2_,
this_.some_object_id as some3_1_2_, someobject1_.id as id2_0_,
someobject1_.version as version2_0_, someobject1_.important_object_id as
important3_2_0_, importanto2_.id as id0_1_, importanto2_.version as version0_1_,
importanto2_.interesting_flag as interest3_0_1_ from a this_
left join b someobject1_ on this_.some_object_id=someobject1_.id
left join c importanto2_ on someobject1_.important_object_id=importanto2_.id
where ((someobject1_.important_object_id is null or (importanto2_.interesting_flag=false)))