tags:

views:

48

answers:

3

I have a list of items. Each item has set of categories. I want to grab all the items of a specific category. This part is simple. The part I am having problems with is getting my query to return the item with all of its categories, not just the one I am filtering on.

session.createCriteria(Item.class)
        .createAlias("categories","category")
        .add(Restrictions.eq("category.name",categoryFilter))

The above code returns the item but only with the category I am filtering on. Is there anyway to say filter the object on this restriction, but return the full object and not the filtered one? I have also tried writing this in HQL with the same results.

A: 

This likely has not much to do with the use of the alias and restriction, but is just a result of default lazy fetching.

In your mapping of Item, you probably have categories set to fetch lazily, which is the default, and generally a good idea.

You can change this mapping to eager, but that's probably a bad idea.

To leave the default fetch lazy but make the specific criteria retrieve eagerly, you can set the fetch mode there, with something resembling

session.createCriteria(Item.class)
    .setFetchMode("categories", FetchMode.EAGER)
    .createAlias("categories","category")
    .add(Restrictions.eq("category.name",categoryFilter))
Don Roby
I have double checked the mapping which is eager and I have set the fetchmode as you have shown. Neither has done the trick.
UmYeah
I've now experimented with a similar situation and indeed this doesn't work.I don't yet have the needed version of hibernate for the fix myself, but there was revision allowing specification of FetchType as a third argument to createAlias, which may do it.See http://opensource.atlassian.com/projects/hibernate/browse/HHH-1696
Don Roby
On my own comment - I do have that overload in Criteria, but it's not FetchType that is the third argument, it's CriteriaSpecification. I haven't seen it correct this issue though.The jira referenced was for adding this overload to DetachedCriteria, which isn't in play here.
Don Roby
I tried setting the third argument as Left_Join which has the usual results. I also tried using Full_Join which created a broken SQL query.
UmYeah
+2  A: 

It appears there really is some nasty interaction between FetchMode and createAlias, which looks like a bug to me.

There's some discussion of this at https://forums.hibernate.org/viewtopic.php?t=944439 with one of the developers saying emphatically that it's correct behavior and won't be fixed.

The discussion also contains potential workarounds though.

Try using a nested criteria instead of an alias:

session.createCriteria(Item.class)
   .createCriteria("categories")
       .add(Restrictions.eq("name",categoryFilter))

With the collection mapped as eager, this seems to work for me. Not sure of interaction with using FetchMode on the outer criteria.

Don Roby
A: 

If it is the bug I reported a while ago: My usual work-around is only fetch the id's of the matching items, and then select the items with their categories in a follow-up query:

List<Serializable> ids = session.createCriteria(Item.class)
    .createAlias("categories","category")
    .add(Restrictions.eq("category.name",categoryFilter))
    .setProjection(Projections.id())
    .list();

List<Items> items = session.createCriteria(Item.class)
    .add(Restrictions.in("id", ids)
    .createAlias("categories","category")
    .list();
meriton