Reputation: 2652
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.
Upvotes: 6
Views: 4326
Reputation: 12196
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:
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.
Upvotes: 6