Question

I'm still quite new to Spring, and I've found it to irritating making all these CRUD DAOs, so I've made a "public class GenericCRUDDAO extends HibernateDaoSupport implements CRUDDAO". In my service objects I then simply say something like

private GenericCRUDDAO<User, Integer> userDAO = new GenericCRUDDAO<User, Integer>();

and no more do I have to write simple DAOs and wire them up. Yay! Except for one thing I'm sure all you experienced Spring developers see right away: I cannot get the Hibernate template inside the GenericCRUDDAO, so doing

HibernateTemplate ht = getHibernateTemplate();

gives me a ht that is null. Not so good. I thought of wiring it in, meaning making a genericCRUDDAO bean and then setting a static AnnotationSessionFactoryBean, but that still wouldn't give me a HibernateTemplate. Any suggestions on how I work around that so that I can have my Hibernate Template?

Any more issues with making a generic CRUD DAO I should be thinking about?

Cheers

Nik

Was it helpful?

Solution

For many, HibernateTemplate and HibernateDaoSupport are on the outs, and instead injecting a SessionFactory is preferred. Not everyone, mind you, but it is a trend, which I adopted not too long ago, removing HibernateTemplate from my own generic DAO.

This blog has a pretty good summary.

The author's examples should be able to help you get to where you want to be.

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top