I have the following domain objects:
class User {
String name
Transaction transaction
static constraints = {
transaction nullable: true
}
}
class Transaction {
boolean successful
User user
static belongsTo = User
}
I want to select all users
that have no successful transaction. This means I want the users without any transaction (transaction == null
) and the users that have a transaction with the successful value false
(transaction.successful == false
). I want to do this with the Criteria API (because this can be combined with other conditions based on user input).
I tried this:
def c = User.createCriteria()
def results = c {
or {
isNull 'transaction'
transaction {
eq 'successful', false
}
}
}
However this gives me only the users that have a transaction (with the successful value false
). But I do not get the users where transaction is null
The following code shows how I created some sample data:
def createUserAndTransaction(String name, Boolean successful = null) {
User u = new User(name: name)
if (successful != null) {
Transaction t = new Transaction(user: u, successful: successful)
u.setTransaction(t)
}
u.save()
}
def init = { servletContext ->
createUserAndTransaction 'john', true
createUserAndTransaction 'mike', false
createUserAndTransaction 'pablo'
}
My criteria query only returns mike
in this case. But I want mike
and pablo
. What am I missing?
So the problem is that it defaults to an inner join. You have to create an alias for the table and define its join type:
createAlias("transaction", "t", CriteriaSpecification.LEFT_JOIN)
or {
isNull("t")
eq("t.successful", false)
}