Hi,
I have two tables: OWNER (ownerId, name) and CAR (carId,ownerId,color,make,model).
Owner class looks like this: Owner{ownerId,name,cars}.
Car class looks like this: Car{carId,owner,color,make,model}.
As you can see, Car object has many-to-one relationship with Owner.
I create Criteria object like this:
Criteria c=session.createCriteria(Owner.class);
c.add(Expression.eq("name","John"));
And I add a filter on Car collection (name="colorFilter", param="color", condition="color=:color") like this:
session.enableFilter("colorFilter").setParameter("color","red");
As of now I have only one owner named John, so this query returns a single Owner object. John has 3 cars: red, green and blue, so Owner.cars for John contains 1 Car object (red one, according to the enabled filter).
So this works fine: Criteria are used to find top-level object (Owner), and filter is used to narrow the data in collection (Cars), since Criteria do not apply to collections.
Now I change my query like this:
Criteria c=session.createCriteria(Owner.class);
c.add(Expression.eq("name","John"));
c.createAlias("cars","crs");
c.add(Expression.eq("crs.make","Honda"));//one of John's cars is red Honda
And I set the color filter like this:
session.enableFilter("colorFilter").setParameter("color","black");
Now nothing comes back - no Owner objects are being returned at all. It's true that John has no black cars, but I would expect to get an Owner object back, with an empty collection of cars? After examining the SQL generated by Hibernate I saw that for some reason the filter condition was imported into the criteria SQL.
I'm guessing this is happening because criteria included alias to CAR table. What I don't understand is where does this dual approach come from? If Criteria is used to select the top-level object (Owner), and filters are used to control collections, then why are filters affecting the Criteria? Is this a bug of some sort?
I would appreciate it if someone could shed some light on this problem.
Thanks,
Bratek
|