I might be using the wrong word so when I say Business Object (BO) I mean a class with a reference to the class that's mapped to a database-table with Hibernate, as well as business logic.
The problem I'm facing is instantiating the right BO for subclasses without using reflection or instanceof.
For example imagine I've got a Pen-table with a single reference to an Animal-table which in turn have got two sub-tables Cat and Dog (all one-to-one references). The classes look somewhat like this:
public class Pen {
private Animal a;
// Getters and setters
}
public class Animal {
// Getters and setters
}
public class Dog extends Animal {
// Getters and setters
}
public class Cat extends Animal {
// Getters and setters
}
public class PenBO {
private Pen p;
public AnimalBO getAnimalBO() { ... }
}
public interface Action {
void visit(DogBO dbo);
void visit(CatBO cbo);
}
public class Sound implements Action {
void visit(DogBO dbo) { ... }
void visit(CatBO cbo) { ... }
}
public interface AnimalBO {
void accept(Sound s);
}
public class DogBO implements AnimalBO {
Dog d;
void accept(Sound s) {
s.visit(this);
}
}
public class CatBO implements AnimalBO {
Cat c;
void accept(Sound s) {
s.visit(this);
}
}
Then I just work with the BOs instantiating them like this inside the get-methods of the BOs:
Pen p = ... // Get or load from database
PenBO pbo = new PenBO();
pbo.setPen(p);
Then I use the classes like this:
pbo.getAnimalBO().accept(new Sound());
It's the getAnimalBO-method that I'm working on. I want it to return the right instance of the BOs based on the Animal-instance of Pen.
I "could" use instanceof checking on the actual Animal from the current Pen but that's obviously not pretty. Another alternative I was thinking of was using reflection to get the class-name and add "BO" afterwards and get an instance of that, however it's also pretty ugly.
I've tried wrapping another visitor-pattern around getAnimalBO but it can't pick the right visit-method without casting and I don't want to add accept-methods to the non-BO classes.
If there's no clever way to get that method to work efficiently is something wrong at the core? I haven't really found any best practices for Hibernate. Some examples of Hibernate and the visitor pattern just add the accept-methods to the mapped classes which can't be good...