This seems not to be a very new problem, but still an unsolved one. As mentioned in the following topic:
http://forums.hibernate.org/viewtopic.p ... e2db7ed39d
"If you have a 1:n relation between tables A and B, and you add a restriction to B and want to fetch A and B eagerly, the question would be what happens when you want to navigate from A to B.
Should you only see the data in B that matches the restriction, or should you see all Bs that are related to A?"
In my case I need to see ALL the data in B - eagerly fetched. I'd like to submit only one query and after that i want to close the session. (Because the retrieved objects shouldn't be changed and I want to avoid any DB access after retrieval). The good news is that this is possible with HQL using a subquery. My query looks like this:
Code:
select distinct parent from Parent parent left join fetch parent.children child where parent in (select c.parent from parent.children c where c.childProperty like '%whatever%')
I use this query in the following way:
Code:
Query query = session.createQuery(queryString);
query.setReadOnly(true); // for performance reasons
query.setCacheMode(CacheMode.IGNORE);
Transaction t = session.beginTransaction();
t.begin();
parentObjects = q.list();
t.commit();
session.close(); // no lazy fetching possible after this point
Now the bad news: My boss is asking to use the Criteria API and after trying for many days I still found no solution to do exactly the same thing with Criterias. At least none that performs as well as the HQL solution. Is there anything bad with this query? Or is anything wrong of using Hibernate in this context?
Sorry for posting that much, but i think i should post my Criteria solution too:
Code:
Criteria criteria = session.createCriteria(Parent.class);
criteria.setLockMode(LockMode.READ); // for performance reasons
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
DetachedCriteria det = DetachedCriteria.forClass(Child.class);
det.setProjection(Projections.property("parent_id")); // yes, it was necessary to add an extra foreign key id property to the child :-(
det.add(Expression.like("childProperty", "%whatever%");
criteria.add(Property.forName("id").in(det));
Of course all the sets in the mappings were mapped with fetch="join" and mutable="false" to get the same result as with the HQL query. However, the HQL solution performs much better than the criteria solution.
What I miss:
1. A correlated subquery which can access collections from its related parent -> Something like DetachedCriteria.forCollection(Child.class, "parent.children", "child");
2. Something like an Expression.in("alias", DetachedCriteria) because I don't like to compare id's manually when i want to compare objects.
3. Any proposition which convert the HQL on top into a working Criteria construct are welcome!
Thanks in advance