Hibernate Made Easy: Simplified Data Persistence with Hibernate and JPA (Java Persistence API) Annotations

Category: Humanities
Author: Kerri Sheehan
4.3
This Month Stack Overflow 1

Comments

by anonymous   2019-01-13

Java Generics to the rescue! Prepare to be amazed.

Your abstract entity (useful if you want to define methods to use in things like, for example, generic controller classes):

public abstract class AbstractEntity<ID extends Serializable> implements Serializable {

    public abstract ID getPrimaryKey();//I simply put this here as an example
}

Create the generic DAO interface:

public interface IGenericDAO<T extends AbstractEntity<ID>, ID extends Serializable> {
    T findByPrimaryKey(ID id);

    T save(T entity);

    void delete(T entity);

    List<T> saveAll(List<T> entities);
    .
    .
    .
}

Then, define your abstract generic DAO:

public abstract class AbstractHibernateDAO<T extends AbstractEntity<ID>, ID extends Serializable> implements IGenericDAO<T, ID> {
    protected Class<T> persistentClass;

    protected AbstractHibernateDAO(){}
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public AbstractHibernateDAO(Class c) {
        persistentClass = c;
    }

    @Override
    @SuppressWarnings("unchecked")
    public T findByPrimaryKey(ID id){
        return (T) HibernateUtil.getSession().get(persistentClass, id);
    }


    @Override
    public T save(T entity){
        HibernateUtil.getSession().saveOrUpdate(entity);
        return entity;
    }

    @Override
    public List<T> saveAll(List<T> entities){
        for(int i = 0; i < entities.size(); i++){
            HibernateUtil.getSession().saveOrUpdate(entities.get(i));
        }
        return entities;
    }

    @Override
    public void delete(T entity){
        HibernateUtil.getSession().delete(entity);
    }
    .
    .
    .
}

DAO interface for entity (For this example, I'm using Integer as the primary key):

public interface IMyEntityDAO extends IGenericDAO<MyEntity, Integer> {
}

Now (drum roll), you are ready to lay some concrete (classes)...

DAO:

public class MyEntityDAO extends AbstractHibernateDAO<MyEntity, Integer> implements IMyEntityDAO {
    public MyEntityDAO() {
        super(MyEntity.class);
    }
}

MyEntity:

@Entity
@Table(name = "my_entity_table")
public class MyEntity extends AbstractEntity<Integer>{

    @Id
    @Column(name = "index")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

 public Integer getPrimaryKey (){
       return id;
 }
    .
    .
    .
}

Boom. (Mic drop)

Let me know if you need further explanation!

I can't rightfully post this without giving credit to Cameron McKenzie and his amazing book here . Which opened my eyes to a whole new world realizing the power of generics.