It seems that in Grails 2.x, if you have a domain class association, and you try to run a createCriteria using or
on that relation + another query, the or
will ignore the other query and just use the results of the nested association. I realize this may be a little confusing, so here is an example:
class Passenger {
Long id
Boolean isDriving
}
class Car {
Long id
Passenger passenger
Boolean isMoving
static constraints = {
passenger nullable: true
}
}
and a 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
}
}
This same code worked in older versions of Grails, but doesn't not seem to work now -- does anyone know of a good workaround to this, other than running multiple queries?
UPDATE:
Post Grails 2.x, Criteria by default uses inner
join, but for this particular case outer
join has to be used as passenger association will not allow to follow or
condition if it is an inner
join and passenger is not set to car.
import org.hibernate.Criteria
def queryResults = Car.createCriteria().list() {
createAlias('passenger', 'passenger', Criteria.LEFT_JOIN)
or {
eq('isMoving', true)
eq('passenger.isDriving', true)
}
}
来源:https://stackoverflow.com/questions/19390720/grails-2-x-createcriteria-or-doesnt-work-for-nested-associations