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.
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.
This isn't too far from your first example, but you may or may not find it more intuitive?
def result = Advertiser.withCriteria {
eq('id', id)
fetchMode 'foos', FetchMode.JOIN
fetchMode 'foos.bars', FetchMode.JOIN
fetchMode 'bars.baz', FetchMode.JOIN
}