Kriterien verwendet "Inner Join" statt "Links Join" Ansatz standardmäßig meine Abfrage funktioniert nicht so, wie ich es geplant habe
Die Frage ist: wie mache ich GORM generieren left-joins anstelle von inner Join in diesem speziellen Beispiel?
Testbed:
Bestimmten Klassen A, B und C:
class A{
B someObject
}
class B{
C importantObject
}
class C{
boolean interestingFlag
}
Möchte ich auflisten aller Elemente Einer Klasse:
- Ihre B. C-Objekt ist null ODER
- Ihre B. C-Objekt interestingFlag Wert false ist
Was ich bisher ausprobiert:
Diesem Verfahren wird die korrekte Liste Ein, wo B. C null ist (bedingt 2 auskommentiert) ODER eine korrekte Liste Ein, wo B. C. interestingFlag = false (egal ob conditional 1 ist auskommentiert oder nicht). Wenn beide Bedingungen sind unkommentierte es gibt nur eine Liste von Elementen, bei denen A. B. C. interestingFlag = false (A. B. C = null Bedingung ignoriert)
//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
}
}
}
}
Bearbeiten:
Wie gewünscht, in Kommentar-ich bin ein einfügen von hibernate generierten 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=?)))
Wenn ich kopieren und fügen Sie ihn in den pgAdmin-Abfrage-tool direkt mit ein paar Sachen geändert (inner joins geändert, um Links verbindet, und sofern die interestingFlag = "false" - parameter) funktioniert alles wie ich wollte (ich bekomme beide A. B. C = null und A. B. C. importantFlag = false Objekte)
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)))
InformationsquelleAutor der Frage Andrzej Bobak | 2013-06-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Getestete und funktionierende Lösung:
InformationsquelleAutor der Antwort Andrzej Bobak
Verwenden Sie left join um dies zu erreichen. Sollte dies funktionieren, aber ich habe es noch nicht getestet live.
Eidt: das basiert auf diesem post: http://grails.1312388.n4.nabble.com/CriteriaBuilder-DSL-Enhancements-td4644831.html dies sollte auch funktionieren:
Bitte posten Sie Ihre Ergebnisse auf beide Lösungen.
Edit 2: Dies ist eine Abfrage, die genau eine situation, die du beschrieben hast, unterscheidet sich aber von Ihrem Beispiele. Sie müssen von hier aus starten, verwenden Sie showSql Debuggen generierten SQLs und hantieren mit Links verbindet.
InformationsquelleAutor der Antwort Tomasz Kalkosiński
War ich in der Lage zu erreichen, left outer joins nur mit HQL
InformationsquelleAutor der Antwort argoden