I have a couple scenarios where I want to retrieve a single Advertiser
and eager fetch most of its object graph. I definitely don't want to do this by default, so I've been searching for the right way to do this for a single query. This is what I've come up with so far:
Advertiser.createCriteria().get {
eq('id', id)
createAlias('foos', 'foos', CriteriaSpecification.LEFT_JOIN)
createAlias('foos.bars', 'bars', CriteriaSpecification.LEFT_JOIN)
createAlias('bars.baz', 'bazzes', CriteriaSpecification.INNER_JOIN)
}
This works, but I dislike it for a couple reasons.
- It seems like a very indirect and unintuitive way to say "just join the dang tables please."
- There is no compile time checking. If the
foos
association didn't exist on an Advertiser
, the compiler would not care.
Here's how I'd really love to see it work:
Advertiser.where {
id == id
foos {
bars {
baz
}
}
}
But this doesn't do any joining; apparently, if you're not actually specifying conditions for that property (>
, <
, ==
, etc) it will just ignore you.
What are my options? How can I, at bare minimum, make this more intuitive to read? Looking for the closest to my ideal as I can get.
Edit
I've tried some of the suggestions below and things aren't working, and it may be partially because I'm not getting my syntax right. Let's say that I need to eager fetch an additional 1st level association called whatsits
I'm trying to do it this way:
Advertiser.withCriteria {
idEq(id)
whatsits
foos {
bars {
baz
}
}
}
I've also tried
Advertiser.withCriteria {
idEq(id) && whatsits && foos {
bars {
baz
}
}
}
But different approaches yield different exceptions, strange looking queries, etc.