I have the following association in a domain I'm working on (not actually pirates unfortunately). A ship has many pirates. I want to be able to find all ships that have a captain and do not have any land lubbers on the crew.
class Pirate {
String name
Rank rank
enum Rank {
CAPTAIN,
DECK_HAND,
LAND_LUBBER
}
}
class Ship {
static hasmany = [crew:Pirate]
}
I'm trying to use Hibernate criteria as in the long run I'd like this to be a named query that I can chain with other queries. Here is the criteria I'm using.
def pirateShips = Ship.withCriteria {
crew {
eq('rank', Pirate.Rank.CAPTAIN)
not {
eq('rank', Pirate.Rank.LAND_LUBBER)
}
}
}
When I create the following entities I don't get the expected results.
def blackbeard = new Pirate(name:'Blackbeard', rank:Pirate.Rank.CAPTAIN).save()
def deckHand = new Pirate(name:'Deck Hand', rank:Pirate.Rank.DECK_HAND).save()
def landLubber = new Pirate(name:'Land Lubber', rank:Pirate.Rank.LAND_LUBBER).save()
def ship = new Ship(name:'Ship 1', crew:[blackbeard]).save()
def infiltrator = new Ship(name:'Ship 2', crew:[blackbeard, landLubber]).save()
def normalShip = new Ship(name:'Ship 3', crew:[blackbeard, deckHand]).save(flush:true)
Running the afore mentioned query results in all 3 ships being returned when I would expect only Ship 1 and Ship 3 to be returned (Ship 2 has a pesky land lubber which is of no use to me).
Is there a way to use the criteria API to generate such a query? If not how would I go about writing a query in HQL?