Hibernate version: 3.5.6
The guts of my problem is if an entity has a collection that uses the subselect fetch strategy, Hibernate.initialize() does not initialize all collections if the collection passed to initialize() happens to be in either the 2nd level or the session cache.
An example:Lets say the entity model is a House has many Rooms and each Room has many Lights:
Code:
@Entity
public class House {
// ...
@OneToMany(cascade=CascadeType.ALL) @JoinColumn(name="House_Id") @Fetch(FetchMode.SUBSELECT)
public Set<Room> getRooms() {return rooms;}
public void setRooms(Set<Room> value) {this.rooms = value; }
// ...
}
@Entity
public class Room {
// ...
@OneToMany(cascade=CascadeType.ALL) @JoinColumn(name="Room_Id") @Fetch(FetchMode.SUBSELECT)
public Set<Light> getLights() {return lights;}
public void setLights(Set<Light> value) {this.lights = value; }
// ...
}
@Entity
public class Light {
// ...
}
Since I want to find all Houses that match a criteria and ensure that each House's Room collection is initialized as well as each Room's Light collection, I've been using something along the lines of:
Code:
Session session = // ...
List<House> houses = session.createCriteria(House.class).list();
House house = // .... get first house in list
Hibernate.initialize(house.getRooms());
Room aRoom = // ... get first room from house collection
Hibernate.initialize(aRoom.getLights());
// close the session
Because the Light collection is annotated with FetchMode.SUBSELECT, the call to Hibernate.initialize(room.getLights()) causes all Rooms contained by all Houses to have their Light collection initialized. This is what I want to happen.
However, there are problems if (for whatever reason) the Light collection that is passed to Hibernate.initialize() happens to already been in either the session or 2nd level cache.
When a collection is passed to initialize(), Hibernate checks the session and 2nd level cache. If the collection can be found in either cache, the database is not queried. Because there is no need to query the database (for this collection), Hibernate does not perform the subselect. Hence, in the example above, if the Light collection of aRoom is in a cache, all of the other Light collections for all the other Rooms and Houses remain uninitialized.
So my question is
Is there a better way to force Hibernate to perform a subselect beyond iterating over each member of the collection(s) and calling initialize()? What would be awesome is if I did not have to worry about triggering a particular condition to get all of those collections initialized.