Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Hibernate DAO with generics

I've found a few tutorials on how to build a Hibernate DAO with generics, but they all use EntityManager instead of a SessionFactory. My question is how to build a DAO with generics using SessionFactory. I have the below so far:

Interface:

public interface GenericDao<T> {

    public void save(T obj);
    public void update(T obj);
    public void delete(T obj);
    public T findById(long id);
}

Class:

@Repository
public class GenericDaoImpl<T> implements GenericDao<T> {

    @Autowired
    private SessionFactory sessionFactory;

    public void save(T obj) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.save(obj);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    public void update(T obj) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.update(obj);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    public void delete(T obj) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.delete(obj);
            tx.commit();
        } catch (HibernateException e) {
            if(tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    public T findById(long id) {
        // ??
        return null;
    }

I'm unsure how to go about findById using generics. I believe the other methods are right, but correct me if I'm wrong.

SIDE QUESTION: Is using EntityManager more beneficial than using SessionFactory? I saw a few posts on the subject, but would like a few more opinions.

like image 898
Jake Miller Avatar asked Jun 26 '16 23:06

Jake Miller


People also ask

What is generic DAO in hibernate?

GenericDAO is a class that can be extended to make individual DAOs. A basic domain-object-specific DAO is created by extending GenericDAO and specifying the domain object type with generic type parameters. The default implementation can be customized by adding and/or overriding methods.

What is generic DAO?

GenericDAO is a method to reduce boilerplate sources codes. EmployeesResource class. CRUD operations on WEB API.

Is hibernate a DAO framework?

Hibernate as you probably know is a object-relational mapping framework implemented using Java language. A DAO can be implemented using Hibernate or even JDBC.

How can Spring data JPA simplify your data access layer?

One of the core objectives of Spring Data JPA is to reduce your code and simplify your Data Access Layer, while still maintaining a rich and full-featured set of functionality. To make this possible, Spring DATA JPA allows you to build intelligent Spring Repository stereotyped interfaces.


1 Answers

You need to have access to the Class<T> from within that method. You have two options, you can pass the Class<T> into the method:

public T findById(long id, Class<T> clazz) {
    // method implementation
}

Or you can pass the Class<T> into the constructor of the class for use in the method:

@Repository
public class GenericDaoImpl<T> implements GenericDao<T> {

    private Class<T> clazz;

    protected GenericDaoImpl(Class<T> clazz) {
        this.clazz = clazz;
    }

    // other methods omitted

    public T findById(long id) {
        // method implementation
    }
}

And subclasses would pass their class into the superclass:

public class UserDao extends GenericDaoImpl<User> {
    public UserDao() {
        super(User.class);
    }
}

Then, using your clazz instance you can get the entity in your generic method using the Session#get method:

T entity = session.get(clazz, id);

See the following questions for more information:

  • How to get a class instance of generics type T
  • Get object by ID in Hibernate

As far as the side question, the EntityManager is part of JPA (the Java Persistence API). Developing your application using the Java API specification instead of the Hibernate API allows your application to not become dependent on Hibernate. This allows you to switch between popular JPA implementations like Hibernate, OpenJPA, or TopLink without making and changes to your code.

This question has more information on the difference.

like image 96
blacktide Avatar answered Oct 06 '22 12:10

blacktide