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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3573479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:28:32  来源:igfitidea点击:

How to create a Generic DAO class using Hibernate Context sessions

javahibernatespringgenericsdao

提问by jai

I'm trying to implement a Generic DAO using the Hibernates Context Sessions. Following was my shot:|

我正在尝试使用 Hibernates 上下文会话来实现通用 DAO。以下是我的镜头:|

import java.io.Serializable;

public interface GenericDao<T, ID extends Serializable> {

 /** 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<T, ID extends Serializable> implements
  GenericDao<T, ID> {
 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:

应用上下文:

<bean id="domainDao" class="com.foo.dao.DomainDao">
  <property name="sessionFactory">
   <ref bean="sessionFactory"></ref>
  </property>

 </bean>

 <bean id="domainDao2" class="com.foo.dao.GenericDaoImpl">
  <property name="sessionFactory">
   <ref bean="sessionFactory"></ref>
  </property>

 </bean>
 <tx:annotation-driven transaction-manager="txManager" />


 <bean id="txManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
 </bean>

Ours is a new application which we are trying to implement using Spring 3.0.3 and Hibernate 3.5.5.

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

Q1. Although I did implement it and is working, did I do in the correct way?

一季度。虽然我确实实施了它并且正在工作,但我是否以正确的方式做?

Q2. How can I implement find()operation using generics?

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

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

This line is giving compilation error.

这一行给出了编译错误。

UPDATE: The error is because the first param is of type Class.

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

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

Q3. How to convert Tto T.class?

Q3。如何转换TT.class

回答by axtavt

The following trick is often used in generic DAO classes to access type parameters of actual subclasses:

以下技巧常用于泛型 DAO 类来访问实际子类的类型参数:

public abstract class GenericDAO<T, ID extends Serializable> {  
    private Class<T> persistentClass;  
    ...

    @SuppressWarnings("unchecked")
    public GenericDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    public T get(ID id) {
        return (T) session.get(persistentClass, id);
    }

    ...
}

And the actual DAO subclass:

和实际的 DAO 子类:

public class FooDAO extends GenericDAO<Foo, Long> {}

回答by Abhinav Sarkar

The generics cannot be used in that way. Change your GenericDAOImplto have a constrctor that takes the class and use that class in the session.getcall. See the example below (it uses JPA instead of Hibernate specific classes).

不能以这种方式使用泛型。更改您GenericDAOImpl的构造函数以获取该类并在session.get调用中使用该类。请参阅下面的示例(它使用 JPA 而不是 Hibernate 特定的类)。

public class GenericDao<T> {

    @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<T> type, final String id) {
        return em.find(type, id);
    }

    public void delete(final T entity) {
        em.remove(entity);
    }

}

public class PersonDao extends GenericDao<Person>{

    public Person get(final String id) {
        return get(Person.class, id);
    }

}

Also, it is better to put @Transactionalannotations on business or data services, not on DAOs.

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