2016-10-25 8 views
1

In Grails 2.5.4 habe ich Probleme mit einer Disjunktion in Unterabfragen. Wenn ich eine Abfrage wie die folgende habe:Verwenden von Disjunktion (logisch oder) in Grails-Unterabfragen

DomainObj.createCriteria().list { 
    def criteria = new DetachedCriteria(DomainObj2).build { 
     or { 
      eq('prop1', someVal) 
      eq('prop2', someVal) 
      eq('prop3', someVal) 
     } 
     projections { 
      distinct('id') 
     } 
    } 
    inList('prop', criteria) 
} 

Der 'oder' Teil der Abfrage schlägt mit einer Nullzeigerausnahme fehl. Der Grund scheint in AbstractHibernateCriterionAdapter zu sein, der Code sucht nach einer PersistentEntity für die DetachedCriteria, die nie zugewiesen wird.

Die einzige Abhilfe, die ich gefunden habe, ist die Abfrage wechseln mehr Unterabfragen wie folgt zu verwenden:

def criteria1 = new DetachedCriteria(DomainObj2).build { 
      eq('prop1', someVal) 
     projections { 
      distinct('id') 
     } 
    } 
    def criteria2 = new DetachedCriteria(DomainObj2).build { 
      eq('prop2', someVal) 
     projections { 
      distinct('id') 
     } 
    } 
    def criteria3 = new DetachedCriteria(DomainObj2).build { 
      eq('prop3', someVal) 
     projections { 
      distinct('id') 
     } 
    } 
    DomainObj.createCriteria().list { 
     or { 
      inList('prop', criteria1) 
      inList('prop', criteria2) 
      inList('prop', criteria3) 
     } 
    } 

die das Problem ausweicht, und ist wirklich nicht ideal. Irgendeine Idee, was schief geht?

aktualisieren

So nach etwas mehr umsah, fand ich this issue auf Github. Was ich erlebe, ist ein Fehler, der in grails-data-mapping Version 5.0.2 behoben wurde. Für jeden, der in Zukunft nach diesem Problem sucht, sieht es so aus, als ob Sie entweder ein Upgrade durchführen oder die oben erwähnte verrückte Problemumgehung verwenden müssen.

+0

Was versuchen Sie zu tun? – injecteer

Antwort

1

Sie könnten wahrscheinlich die oben arbeiten Nest vereinfachen:

private DetachedCriteria getCriteria(prop,val) { 
     return new DetachedCriteria(DomainObj2).build { 
      eq(prop,val) 
     projections { 
      distinct('id') 
     } 
    } 
    DomainObj.createCriteria().list { 
     or { 
      inList('prop', getCriteria('prop1','somVal')) 
      inList('prop', getCriteria('prop2','somVal')) 
      inList('prop', getCriteria('prop3','somVal')) 
     } 
    } 

Persönlich würde ich wahrscheinlich entweder nur do a findAll oder nur eine HQL-Abfrage ausführen, wenn sich herausstellt, nicht die aktuelle Methode aufgrund einiger verwenden können Einschränkung, da ich selbst kein Experte in diesem Bereich bin.

//where d.domainObject2 is the binding of DomainObj2 within DomainObj 
    String query="select new map(d.id) from DomainObj d left join d.domainObject2 d2 where d2.field in (:someList)" 
def input=[] 
input.someList=[1,2,3] //The or segments 
    def results=DomainObj.executeQuery(query,[],[readOnly:true,timeout:15,max:-1]) 
Verwandte Themen