GenericDao
Well, to me, if your GenericDAO is 'generic', then you might need only one instance, and do all with that single instance.
I'm sure it doesn't bother you to wire on instance, it's at the repetition that you get mad (and I agree with you).
For example, you could pass the Entity class to a generic method.
- public void save(Class, E...) : lets you save one or more instances of E type, E being one of your entities.
- public E load(Class, Long id) : loads an entity.
...
/** Assuming the entities have a superclass SuperEntity with getIdent(). */
public class GenericDaoImpl implements GenericDao {
/** Save a bunch of entities */
public void save(SuperEntity... entities) {
for(SuperEntity entity : entities) {
getSession().save(entity);
}
}
/** Load any entity. */
public <E extends SuperEntity> E load(Class<E> entityClass, Long ident) {
return (E)getSession().load(entityClass, ident);
}
// other generic methods
}
Variant
In our applications, we actually have a variant for this. Because we have many specific request for each Dao, we need the specific Dao classes anyway (create the class and wire it), so to avoid the special case of a Dao that would not be defined, we make the specific Dao classes right away.
Coding
But in no way we repeat the code. All our Daos extends the GenericDao, providing in the constructor the Class parameter that is needed. Sample code (not complete, simple to get the basic idea):
public abstract class GenericDaoImpl<E extends SuperEntity>
implements GenericDao<E> {
/** Available for generic methods, so it is not a parameter
* for the generic methods. */
private final Class<E> entityClass;
protected GenericDaoImpl(Class<E> entityClass) {
this.entityClass = entityClass;
}
// generic implementation ; can be made efficient, as it may
// send the orders as a batch
public void save(E... entities) {
for(SuperEntity entity : entities) {
getSession().save(entityClass, entity.getIdent());
}
// possibly add flushing, clearing them from the Session ...
}
// other generic methods
}
public class PersonDaoImpl extends GenericDaoImpl<Person>
implements PersonDao {
/** Constructor, instanciating the superclass with the class parameter. */
public PersonDaoImpl() {
super(Person.class);
}
/** Specific method. */
public List<Person> findByAge(int minAge, int maxAge) {
//....
}
}
Wiring
Wiring all the beans is not a fatality. Nowadays, there are many autowiring policies, you don't have to worry about it. See them in Spring
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config