Generic DAO

Problem

Redundant/Duplicate CURD operations code for all entities in their respective DAO’s.

Solution

Now we have encapsulated the CURD operations in one Generic class and make other other DAO’s extend the generic dao.

Hibernate Basic Setup

Configuration

hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>

        <!-- SQL dialect -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>

        <mapping class="com.pos.model.BaseEntity" />
        <mapping class="com.pos.model.Item" />
    </session-factory>

</hibernate-configuration>

 

Hibernate Utils

SessionFactory is made Singleton here

package com.util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

public class HibernateUtils {

    private HibernateUtils() {
    }

    private static SessionFactory sessionFactory;

    private static SessionFactory buildSessionAnnotationFactory() {

        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
                .configure() // configures settings from hibernate.cfg.xml
                .build();
        try {
             sessionFactory = new MetadataSources(registry)
                    .buildMetadata().buildSessionFactory();
        } catch (Exception e) {
            e.printStackTrace();
            StandardServiceRegistryBuilder.destroy(registry);
        }
        return sessionFactory;
    }

    public static synchronized SessionFactory getSessionAnnotationFactory() {
        if (sessionFactory == null)
            sessionFactory = buildSessionAnnotationFactory();
        return sessionFactory;
    }
}

Entities

Base Entity

package com.model;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    @Column(name = "ID", nullable = false)
    protected int id;

    @Column(name = "INIT_DATE")
    @Temporal(TemporalType.TIMESTAMP)
    private Date initDate = new Date();

    @PrePersist
    public void setCreationDate() {
        this.initDate = new Date();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Date getInitDate() {
        return initDate;
    }

    public void setInitDate(Date initDate) {
        this.initDate = initDate;
    }
}

 

Item Entity – For Example

package com.model;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

/**
 * The persistent class for the ITEM database table.
 * 
 */
@Entity
@Table(name = "ITEM")
@AttributeOverride(name = "id", column = @Column(name = "ITEM_ID", nullable = false))
public class Item extends BaseEntity {
    private static final long serialVersionUID = 1L;

    @Column(name = "`DESC`", length = 45)
    private String desc="";

    @Column(name = "NAME", nullable = false, length = 45)
    private String name="";

    @Column(name = "QTY")
    private float qty = 0.0F;

    public Item() {
    }

    public String getDesc() {
        return this.desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getQty() {
        return qty;
    }

    public void setQty(float qty) {
        this.qty = qty;
    }

}

Generic DAO

package com.dao;

import java.util.List;

import com.model.BaseEntity;

public interface GenricDao<T extends BaseEntity> {

    public List<T> get();

    public T get(int id);

    public void save(T t);

    public void update(T t);
    
    public void delete(T t);

}

Generic DAO Impl

package com.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.pos.model.BaseEntity;
import com.pos.util.HibernateUtils;

public class GenericDaoImpl<T extends BaseEntity> implements GenricDao<T> {

    public GenericDaoImpl(Class<T> type) {
        this.type = type;
    }

    protected Class<T> type;

    protected SessionFactory factory = HibernateUtils.getSessionAnnotationFactory();

    @SuppressWarnings("unchecked")
    @Override
    public List<T> get() {
        List<T> list = null;
        Session session = null;
        try {
            session = factory.openSession();
            list = session.createCriteria(type).list();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            if (session != null && session.isOpen())
                session.close();
        }
        return list;
    }

    @Override
    public T get(int id) {
        T t = null;
        Session session = null;
        try {
            session = factory.openSession();
            t = session.get(type, id);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            if (session != null && session.isOpen())
                session.close();
        }
        return t;
    }

    @Override
    public void save(T t) {
        Session session = null;
        try {
            session = factory.openSession();
            session.beginTransaction();
            session.save(t);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            if (session != null && session.isOpen())
                session.close();
        }
    }

    @Override
    public void update(T t) {
        Session session = null;
        try {
            session = factory.openSession();
            session.beginTransaction();
            session.update(t);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            if (session != null && session.isOpen())
                session.close();
        }

    }

    @Override
    public void delete(T t) {
        Session session = null;
        try {
            session = factory.openSession();
            session.beginTransaction();
            session.delete(t);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            if (session != null && session.isOpen())
                session.close();
        }
    }
}

Item DAO

package com.dao;

import com.model.Item;

public interface ItemDao extends GenricDao<Item> {

   // Other Operations/methods specific to this DAO.
}

Item DaoImpl

package com.dao;

import org.hibernate.Session;

import com.model.Item;

public class ItemDaoImpl extends GenericDaoImpl<Item> implements ItemDao {

    public ItemDaoImpl(Class<Item> type) {
        super(type);
    }
    // Implementations of ItemDao methods.
   }

Usage

Now you can use itemDao and access the Basic CURD and other Specific to Item operations.

private ItemDao itemDao = new ItemDaoImpl(Item.class);

In case you need only Basic CURD you can also use like this

private GenricDao<Item> itemDao = new GenericDaoImpl<Item>(Item.class);

 

3 thoughts on “Generic DAO

  1. Very good use case, Good design example, eliminates code duplication and improves code quality and reuse. what You mean to say in the comment is, we will do spring injection rather than instantiating with new operator, so the way is more abstract. Correct Mahi?

    Like

    • Actually i mean if we inject GenericDao in any other class then we are forced to access only basic CURD operations. but if we inject the subclasses(ItemDaoImpl) of GenericDaoImpl then in future we can add more services/methods.

      In our Example we have empty ItemDao. Later we can add additional methods specific to Item.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s