Hibernate: CRUD Generic DAO
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);
}
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).
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.