I prefer convenience libraries to code generation - after all, generated code has to be maintained somehow. And with DAOs, finder methods etc need to be hand-coded anyway.
For a different way of writing DAOs, let me show how the Spring Framework eases DAO implementation, with a source example from the Petclinic (a sample app that comes with the Spring distribution):
Code:
public class HibernateClinic extends HibernateDaoSupport implements Clinic {
public List getVets() {
return getHibernateTemplate().find("from Vet vet order by vet.lastName, vet.firstName");
}
public List getPetTypes() {
return getHibernateTemplate().find("from PetType type order by type.name");
}
public List findOwners(String lastName) {
return getHibernateTemplate().find("from Owner owner where owner.lastName like ?", lastName + "%");
}
public Owner loadOwner(long id) {
return (Owner) getHibernateTemplate().load(Owner.class, new Long(id));
}
public Pet loadPet(long id) {
return (Pet) getHibernateTemplate().load(Pet.class, new Long(id));
}
public void storeOwner(Owner owner) {
getHibernateTemplate().saveOrUpdate(owner);
}
public void storePet(Pet pet) {
getHibernateTemplate().saveOrUpdate(pet);
}
public void storeVisit(Visit visit) {
getHibernateTemplate().saveOrUpdate(visit);
}
}
All of those data access methods are effectively one-liners but still offer proper resource handling (Session opening and closing) and transaction participation. HibernateDaoSupport is a convenience base class that offers a "sessionFactory" bean property and prepares a HibernateTempate instance. You can also choose to instantiate your own HibernateTemplate for any given SessionFactory.
The above methods are just convenience methods that avoid the need for a callback implemenation. The "standard" way of using HibernateTemplate is like as follows. Note that HibernateTemplate will automatically convert HibernateExceptions into Spring's unchecked generic DataAccessException hierarchy. You're free to add any exceptions with business meaning to the DAO method signatures.
Code:
public List findOwners(String lastName) {
return (List) hibernateTemplate.execute(
new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
return session.find("find("from Owner owner where owner.lastName like ?", lastName + "%", Hibernate.STRING);
}
}
});
The HibernateClinic bean is configured in a Spring application context as follows, referencing a SessionFactory defined in the context:
Code:
<bean id="clinic" class="org.springframework.samples.petclinic.hibernate.HibernateClinic">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
Of course, you can also instantiate it without an application context, as it is a simple bean:
Code:
HibernateClinic clinic = new HibernateClinic();
clinic.setSessionFactory(sessionFactory);
All of the above DAO methods automatically participate in transactions driven by Spring's transaction management. Demarcation can happen programmatically or declaratively (on POJOs), and the actual transaction strategy is pluggable. For Hibernate, HibernateTransactionManager (for a single SessionFactory) and JtaTransactionManager are appropriate; both implicitly use ThreadLocal Sessions underneath.
The article at
http://www.hibernate.org/110.html gives a detailed overview. I'll be happy to discuss it further if you're interested.
Juergen