just hi
just hi

Reputation: 45

Spring + Hibernate DAO as generic class

Some time ago I started to learn java EE. I swiftly moved to spring(mvc)+hibernate. As I was learning about databases and integration with spring+hibernate I came up with an idea.

As far as I noticed(and understand) there's a common approach to build an objects structure including configuration files, entities, dao interface and dao implementation(as we're talking just about dbs, not controllers and other applications' layers). I decided to write a generic java class and call it BasicDao. It's a template which takes entity as a type.

This is actually working and I think it's much better than interfaces and implementations, because you need only one class for all entities(if you wanted to write separated implementations for each entity you might end up with a big amount of files).

I also wrote some template functions there so the class is very flexible(no exceptions with types passed to the db). Here's the code

package local.bb.dao;

import java.util.List;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository(value = "basicDao")
@Transactional(propagation = Propagation.REQUIRED,readOnly = true)
public class BasicDao<ENTITY> {

    private Class<ENTITY> data;
    private SessionFactory sessionFactory;

    public BasicDao() {
        this.data = null;
    }

    @Transactional
    public void addRecord(ENTITY t) {
        this.sessionFactory.getCurrentSession().save(t);
    }

    @Transactional
    public void removeRecord(ENTITY t) {
        this.sessionFactory.getCurrentSession().delete(t);
    }

    @Transactional
    public List<ENTITY> getAllRecords() {
        return (List<ENTITY>)this.sessionFactory.getCurrentSession().createCriteria(this.data).list();
    }

    @Transactional
    public <TYPE> ENTITY getRecordByParam(String param, TYPE value) {
        return (ENTITY)this.sessionFactory.getCurrentSession().createCriteria(this.data).add(Restrictions.eq(param, value)).uniqueResult();
    }

    @Transactional
    public <TYPE> List<ENTITY> getRecordsByParam(String param, TYPE value) {
        return (List<ENTITY>)this.sessionFactory.getCurrentSession().createCriteria(this.data).add(Restrictions.like(param, value)).list();
    }

    //  GETTERS / SETTERS

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }


    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Class<ENTITY> getData() {
        return data;
    }

    public void setData(Class<ENTITY> data) {
        this.data = data;
    }


}

The question, finally, is: is it a good approach actually? Because I've never seen such code anywhere(speaking about tutorials on the Internet and books).

Upvotes: 2

Views: 855

Answers (2)

Fritz Duchardt
Fritz Duchardt

Reputation: 11950

Spring likes interfaces since a couple of important mechanism are based on it, e.g. AOP, interceptors. So, if you decide to go without them you have to accept certain limits to Spring functionality. What's more, it will be harder to write Test-Mocks for other classes that depend on your DAOs.

If you want to save code, I suggest you lose the implementation rather than the interface. With Spring JPA you can annotate a DAO interface with as set of annotations, i.e. @Query, @Procedure, @Modifying etc to define how the data is accessed. If you then enable JPA repositories in your application context, Spring will supply the DAO implementation for you.

More information can be found here.

Upvotes: 2

mushfek0001
mushfek0001

Reputation: 3935

Yes you can write generic DAO in hibernate and if it's useful and helps you to reduce substantial amount of code and makes your codebase clean then you should go for it. I have used generic DAO but only for simple CRUD operations. Here is a good read on generic persistence layer.

Upvotes: 0

Related Questions