views:

932

answers:

1

I'd like to use Hibernate's Criteria API for precisely what everybody says is probably its most likely use case, applying complex search criteria. Problem is, the table that I want to query against is not composed entirely of primitive values, but partially from other objects, and I need to query against those object's id's.

I found this article from 2 years ago that suggests it's not possible. Here's how I tried it to no avail, there are other aspect of Hibernate where I know of where this sort of dot notation is supported within string literals to indicate object nesting.

   if (!lookupBean.getCompanyInput().equals("")) {
       criteria.add(Restrictions.like("company.company", lookupBean.getCompanyInput() + "%"));
   }

EDIT:

Here's my correctly factored code for accomplishing what I was trying above, using the suggestion from the first answer below; note that I am even using an additional createCriteria call to order on an attribute in yet another associated object/table:

if (!lookupBean.getCompanyValue().equals("")) {
    criteria.createCriteria("company").add(
           Restrictions.like("company", lookupBean.getCompanyValue() + "%"));
}

List<TrailerDetail> tdList = 
        criteria.createCriteria("location").addOrder(Order.asc("location")).list();
+5  A: 

Not entirely sure I follow your example, but it's certainly possible to specify filter conditions on an associated entity, simply by nesting Criteria objects to form a tree. For example, if I have an entity called Order with a many-to-one relationship to a User entity, I can find all orders for a user named Fred with a query like this:

List<Order> orders = session.createCriteria(Order.class)
    .createCriteria("user")
     .add(eq("name", "fred"))
    .list();

If you're talking about an entity that has a relationship to itself, that should work as well. You can also replace "name" with "id" if you need to filter on the ID of an associated object.

Rob H
+1. You want to be careful with IDs, though - depending on the mapping it may not be necessary (or even legal) to create nested criteria to query associations by id. Hence, in the above example you would use `session.createCriteria(Order.class).add(eq("user.id", 25)).list()`
ChssPly76
And I was going to add that if you have a reference to the associated object in your Java code, you could also pass the entity object itself as an argument to the Restrictions.eq call (e.g. Restrictions.eq("user", user)) instead of the ID. You can easily get such a reference without paying a performance penalty using Session.load(User.class, <id>).
Rob H
Thanks your suggestion worked. Did not have a reference to the associated object. I might edit my question to indicate the replacement code that worked. But how would you nest more than one Criteria if you needed to? I don't need to but that could be problematic. If you only need to nest one though it should probably be the last thing you tack onto the original criteria.Anyway thanks! I've just replaced dozens of lines of code building up an HQL query with a StringBuffer, to about less than 10 lines.
George Jempty
Actually thinking about it a bit more, you probably just always append the original criteria with whatever additional nested criteria you need.
George Jempty