views:

144

answers:

3

Consider the following three Hibernate entities:

public class Car {

  @OneToMany(fetch = FetchType.LAZY)
  @Fetch(FetchMode.SUBSELECT)
  private List<Wheel> wheels;

}

public class Wheel {

  @OneToOne(fetch = FetchType.LAZY)
  private Hubcap hubcap;

}

public class Hubcap {

}

Consider the following Criteria:

Criteria criteria = getSession().createCriteria(Car.class);
List<Car> cars = criteria.list();

for (Car car : cars) {
  Hibernate.initialize(car.getWheels());
}

Is there any way to control the subselect query that will be generated? Specifically I'd like to join in the subselect so that the hubcaps are also fetched when the wheels are fetched. This can of course be accomplished by changing the FetchType to EAGER, but I need something more ad hoc - on a query by query basis.

As the code is currently I'd need to generate another select to fetch the Hubcaps.

A: 

Yes you can do it using criteria but I don't remember how its done, just look for joins in criteria, however I would suggest using HQL rather Criteria is far more readable:

select c 
from Car c join fetch c.wheels
where ...
Omar Al Kababji
I have valid reasons for needing to do this with Criteria, which I'd rather not get into right now unless absolutely necessary. Also, with your HQL solution it won't be applied "automatically" when Hibernate.initialize(car.getWheels()) is called, unless I'm mistaken?
Zecrates
Using the "join fetch" in the HQL will load the wheels colletion eagerly, and you will not need to call Hibernate.initialize() ... try to enable the flag view_sql and check the difference in the query generated with and without the part **join fetch c.wheels**
Omar Al Kababji
Problem is I need to use subselects in order to avoid a cartesian join, as in my actual entity I have multiple OneToMany relations that need to be loaded.
Zecrates
A: 

You can change the fetch type in a criteria query with the setFetchMode method.

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html

kpolice
This won't affect the subselect query that is generated.
Zecrates
A: 

After lots of research it appears that this is impossible at this stage, at least without extending Hibernate.

Zecrates