Q:

Hibernate: CRUD Generic DAO

My web application has got a lot of service tables/entities, such as payment_methods, tax_codes, province_codes, etc.
Each time I add a new entity, I have to write a DAO. The thing is that, basically, they are all the same, but the only difference is the entity class itself.
I know that Hibernate tools can generate the code for me automatically but I can't use them now (don't ask why) so I'm thinking of a Generic DAO. There's a lot of literature about that but I can't put pieces together and make it work with Spring.
It's all about generics I think, it will have four basic methods:

listAll
saveOrUpdate
deleteById
getById

and that's all.

Question:
What's the best practice for not re-inventing the wheel? Isn't there something ready to use, yet?

A:

here's mine
@Component
public class Dao{

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    public <T> T save(final T o){
      return (T) sessionFactory.getCurrentSession().save(o);
    }

    public void delete(final Object object){
      sessionFactory.getCurrentSession().delete(object);
    }

    /***/
    public <T> T get(final Class<T> type, final Long id){
      return (T) sessionFactory.getCurrentSession().get(type, id);
    }

    /***/
    public <T> T merge(final T o)   {
      return (T) sessionFactory.getCurrentSession().merge(o);
    }

    /***/
    public <T> void saveOrUpdate(final T o){
      sessionFactory.getCurrentSession().saveOrUpdate(o);
    }

    public <T> List<T> getAll(final Class<T> type) {
      final Session session = sessionFactory.getCurrentSession();
      final Criteria crit = session.createCriteria(type);
  return crit.list();
    }
// and so on, you shoudl get the idea

and you can then access like so in service layer:
 @Autowired
    private Dao dao;

   @Transactional(readOnly = true)
    public List<MyEntity> getAll() {
      return dao.getAll(MyEntity.class);
    }

A:

Spring Data JPA is a wonderful project that generate DAOs for you, and more! You only have to create an interface (without any implementation):
interface PaymentMethodsDao extends JpaRepository<PaymentMethods, Integer> {}

This interface (via inherited JpaRepository) will automatically give you:
PaymentMethod save(PaymentMethod entity);
Iterable<PaymentMethod> save(Iterable<? extends PaymentMethod> entities);
PaymentMethod findOne(Integer id);
boolean exists(Integer id);
Iterable<PaymentMethod> findAll();
long count();
void delete(Integer id);
void delete(PaymentMethod entity);
void delete(Iterable<? extends PaymentMethod> entities);
void deleteAll();
Iterable<PaymentMethod> findAll(Sort sort);
Page<PaymentMethod> findAll(Pageable pageable);
List<PaymentMethod> findAll();
List<PaymentMethod> findAll(Sort sort);
List<PaymentMethod> save(Iterable<? extends PaymentMethods> entities);
void flush();
PaymentMethod saveAndFlush(PaymentMethods entity);
void deleteInBatch(Iterable<PaymentMethods> entities);

The interface is strongly typed (generics) and automatically implemented for you. For every entity all you have to do is to create an interface extending JpaRepository<T,Integer extends Serializable>.
But wait, there's more! Assuming your PaymentMethod has name and validSince persistent fields. If you add the following method to your interface:
interface PaymentMethodsDao extends JpaRepository<PaymentMethods, Integer> {

  Page<PaymentMethod> findByNameLikeAndValidSinceGreaterThan(
    String name, Date validSince, Pageable page
  );

}

the framework will parse the method name:
findBy (Name like) And (ValidSince greater than)
create the JPA QL query, apply paging and sorting (Pageable page) and run it for you. No implementation needed:
paymentMethodsDao.findByNameLikeAndValidSinceGreaterThan(
  "abc%",
  new Date(),
  new PageRequest(0, 20, Sort.Direction.DESC, "name"
);

Resulting query:
SELECT *  //or COUNT, framework also returns the total number of records
FROM PaymentMethods
WHERE name LIKE "abc%"
  AND validSince > ...

And with paging applied.
The only downside is that the project is rather new and it is relatively easy to hit buts (but it is very actively developed).

A:

Do not write specific dao for each entity. You can implement one generic DAO that does 90% of work for all entities you need. You can extend it in cases you want specific treatment of certain entities.
In project I am currently working on we have such DAO that wraps Hibernate session providing methods similar to those that you described. Moreover we are using ISearch API - the open source project hosted at google code and providing very convenient criteria building interface for Hibernate and JPA.

