Disclaimer: I'm just getting started with Hibernate so this may be very bad (performance wise or other).
I thought I would share how I load lazy associations before the session is detached. In the presentation layer, I use a simple InitNode class to make a tree of associations to load:
Code:
// Specify which lazy associations should be initialized in presentation layer
InitNode animalNode = new InitNode(null, Animal.class);
animalNode.addSubNode("predators", Preditor.class);
animalNode.addSubNode("nicknames", AnimalName.class);
animalNode.addSubNode("habitats", Habitat.class);
InitNode preyNode = new InitNode("prey", Prey.class);
preyNode.addSubNode("nicknames", AnimalName.class);
amimalNode.addSubNode(preyNode);
/*
Makes this sort of tree:
animal
/ / \ \
/ / \ \
/ / \ \
predators nicknames habitats prey
|
nicknames
*/
// Pass this InitNode tree to service layer
Animal myAnimal = so.getAnimalByPk("Monkey",animalNode);
Where InitNode is just a simple class holding:
Code:
String propertyName;
Set<InitNode> subNodes;
Class classToInit;
In the animal DAO called in the service layer:
Code:
public Animal getByPk(String name, InitNode node) {
Animal animal = ...
initialize(animal, node);
return animal;
}
public void initialize(Object o, InitNode node) {
// We're done if there is nothing to initialize
if (node.hasChildren()) {
// Get metadata for this Class
ClassMetadata classMetadata = getSessionFactory().getClassMetadata(
node.getClassToInit());
// For each association
for (InitNode child : node.getSubNodes()) {
// Get the assocition's object
Object ob = classMetadata.getPropertyValue(o, child
.getPropertyName(), EntityMode.POJO);
// Initialize it
Hibernate.initialize(ob);
if (ob instanceof Collection) {
for (Object obj : (Collection) ob) {
initialize(obj, child);
}
}
else {
initialize(ob, child);
}
}
}
}
This is pretty generic so it is easy to add new classes. Of course this could be cleaned up a lot. Hope someone finds this useful!