2013-10-15 12 views
5

Es scheint, dass in Grails 2.x, wenn Sie eine Domain-Klassenzuordnung haben, und Sie versuchen, eine createCriteria mit or für diese Beziehung + eine andere Abfrage auszuführen Die or ignoriert die andere Abfrage und verwendet nur die Ergebnisse der verschachtelten Assoziation. Ich weiß, das ein wenig verwirrend sein mag, hier so ein Beispiel:Grails 2.x createCriteria 'oder' funktioniert nicht für verschachtelte Assoziationen

class Passenger { 
    Long id 
    Boolean isDriving 
} 

class Car { 
    Long id 
    Passenger passenger 
    Boolean isMoving 

    static constraints = { 
     passenger nullable: true 
    } 
} 

und ein Test:

class CarIntegrationTests { 
    @Test 
    void testCar() { 
    Passenger passenger1 = new Passenger(isDriving: true) 
    passenger1.save() 

    Car car1 = new Car(passenger: passenger1, isMoving: false) 
    Car car2 = new Car(isMoving: true) 

    car1.save() 
    car2.save() 

     def queryResults = Car.createCriteria().list() { 
      or { 
       eq('isMoving', true)// This by itself works 

       passenger {// And this by itself works 
        eq('isDriving', true) 
       } 
      }// But OR'd, it only returns the results of the nested part 
     } 

     assertEquals 2, queryResults.size() // Returns 1 
    } 
} 

Dieser gleiche Code in älteren Versionen von Grails gearbeitet, aber scheint nicht nicht zu Jetzt arbeiten - kennt jemand eine gute Problemumgehung, abgesehen von mehreren Abfragen?

+0

Versuchen Sie die Ruhezustandsprotokollierung einzuschalten und sehen Sie, welche SQL generiert wird. Als Work-Around könnten Sie einfach eine hql-Abfrage schreiben, aber Sie sollten nicht –

+0

@JimSosa Yeah Ich werde es mit der Protokollierung versuchen. Ich hatte gehofft, nicht HQL zu verwenden, aber ja, ich muss vielleicht. – Igor

Antwort

10

UPDATE:
Beitrag Grails 2.x Kriterien verwendet standardmäßig inner beitreten, aber für diesen speziellen Fall outer kommen als Fahrgastverband verwendet werden muss nicht or Zustand folgen lassen, wenn es sich um eine inner ist beitreten und der Beifahrer ist nicht auf das Auto eingestellt.

import org.hibernate.Criteria 

def queryResults = Car.createCriteria().list() { 
    createAlias('passenger', 'passenger', Criteria.LEFT_JOIN) 
    or { 
     eq('isMoving', true) 
     eq('passenger.isDriving', true) 
    } 
} 
+0

@GrailsGuy Siehe mein Update. Outer Join muss verwendet werden. – dmahapatro

+0

Hinweis von Grails 3/Hibernate 4+, Kriterien ist veraltet und sollte stattdessen JoinType.LEFT_OUTER_JOIN sein, aber ansonsten immer noch eine perfekte Antwort. – Trebla

Verwandte Themen