如何使用Hibernate Context会话创建Generic DAO类

我正在尝试使用Hibernates Context Sessions实现Generic DAO。 以下是我的镜头:|

import java.io.Serializable; public interface GenericDao { /** Persist the newInstance object into database */ ID create(T newInstance); /** * Retrieve an object that was previously persisted to the database using * the indicated id as primary key */ T read(ID primaryKey); /** Save changes made to a persistent object. */ void update(T transientObject); /** Remove an object from persistent storage in the database */ void delete(T persistentObject); } import java.io.Serializable; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.springframework.transaction.annotation.Transactional; @Transactional @SuppressWarnings("unchecked") public class GenericDaoImpl implements GenericDao { private SessionFactory sessionFactory; public void setSessionFactory(final SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public ID create(final T newInstance) { ID id = null; final Session session = sessionFactory.openSession(); final Transaction tx = session.beginTransaction(); try { id = (ID) session.save(newInstance); tx.commit(); session.close(); } catch (final Exception e) { if (tx != null) { tx.rollback(); } e.printStackTrace(); } finally { if (session.isOpen()) { session.close(); } } return id; } @Override public T read(final ID primaryKey) { T id = null; final Session session = sessionFactory.openSession(); final Transaction tx = session.beginTransaction(); try { id = (T) session.get(T, primaryKey); tx.commit(); session.close(); } catch (final Exception e) { if (tx != null) { tx.rollback(); } e.printStackTrace(); } finally { if (session.isOpen()) { session.close(); } } return id; } @Override public void update(final T transientObject) { final Session session = sessionFactory.openSession(); final Transaction tx = session.beginTransaction(); try { session.saveOrUpdate(transientObject); tx.commit(); session.close(); } catch (final Exception e) { if (tx != null) { tx.rollback(); } e.printStackTrace(); } finally { if (session.isOpen()) { session.close(); } } } @Override public void delete(final T persistentObject) { final Session session = sessionFactory.openSession(); final Transaction tx = session.beginTransaction(); try { session.delete(persistentObject); tx.commit(); session.close(); } catch (final Exception e) { if (tx != null) { tx.rollback(); } e.printStackTrace(); } finally { if (session.isOpen()) { session.close(); } } } } 

的applicationContext:

               

我们正在尝试使用Spring 3.0.3和Hibernate 3.5.5实现一个新的应用程序。

Q1。 虽然我确实实现了它并且正在工作,但我是否以正确的方式做到了?

Q2。 如何使用generics实现find()操作?

 id = (T) session.get(T, primaryKey); 

这一行给出了编译错误。

更新 :错误是因为第一个参数类型为Class

 public Object get(Class clazz, Serializable id) throws HibernateException 

Q3。 如何将T转换为T.class

通用DAO类中经常使用以下技巧来访问实际子类的类型参数:

 public abstract class GenericDAO { private Class persistentClass; ... @SuppressWarnings("unchecked") public GenericDAO() { this.persistentClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } public T get(ID id) { return (T) session.get(persistentClass, id); } ... } 

而实际的DAO子类:

 public class FooDAO extends GenericDAO {} 

generics不能以这种方式使用。 将GenericDAOImpl更改为拥有一个构造函数,该构造函数接受类并在session.get调用中使用该类。 请参阅下面的示例(它使用JPA而不是Hibernate特定的类)。

 public class GenericDao { @PersistenceContext private EntityManager em; public EntityManager em() { return em; } public void create(final T entity) { em.persist(entity); } public void update(final T entity) { em.merge(entity); } protected T get(final Class type, final String id) { return em.find(type, id); } public void delete(final T entity) { em.remove(entity); } } public class PersonDao extends GenericDao{ public Person get(final String id) { return get(Person.class, id); } } 

此外,最好将@Transactional注释放在业务或数据服务上,而不是DAO上。