Рубрики
Без рубрики

ДАО с весной и зимней спячкой

DAO с Spring 3 и Hibernate – фокусируется на управлении транзакциями, управлении сеансами Hibernate, лучших практиках шаблонов Spring и распространенных ловушках.

Автор оригинала: Eugen Paraschiv.

1. Обзор

В этой статье будет показано, как реализовать DAO с помощью Spring и Hibernate . Для базовой конфигурации Hibernate ознакомьтесь с предыдущей статьей Hibernate 5 с Spring .

2. Больше Никаких Весенних Шаблонов

Начиная с Spring 3.0 и Hibernate 3.0.1, Spring HibernateTemplate больше не требуется для управления сеансом Hibernate. Теперь можно использовать контекстные сеансысеансы, управляемые непосредственно Hibernate и активные на протяжении всей транзакции.

Как следствие, теперь рекомендуется использовать API Hibernate напрямую вместо HibernateTemplate. Это позволит полностью отделить реализацию слоя DAO от Spring.

2.1. Перевод исключений Без HibernateTemplate

Перевод исключений был одной из обязанностей HibernateTemplate – перевод низкоуровневых исключений Hibernate на более высокий уровень, общие исключения Spring.

Без шаблона этот механизм по-прежнему включен и активен для всех DAO, аннотированных аннотацией @Repository . Под капотом это использует Spring beanpostprocessor, который посоветует всем @Repository beans со всеми PersistenceExceptionTranslator , найденными в контексте Spring.

Следует помнить, что при переводе исключений используются прокси-серверы. Чтобы Spring могла создавать прокси-серверы вокруг классов DAO, они не должны быть объявлены как final .

2.2. Управление сеансами Гибернации Без шаблона

Когда появилась поддержка Hibernate для контекстных сеансов, HibernateTemplate по существу устарел. На самом деле, Javadoc класса теперь выделяет этот аспект (выделено жирным шрифтом из оригинала):

ПРИМЕЧАНИЕ: Начиная с версии Hibernate 3.0.1, транзакционный код доступа к Hibernate также может быть закодирован в обычном стиле Hibernate. Поэтому для недавно запущенных проектов рассмотрите возможность принятия стандартного стиля Hibernate 3 для кодирования объектов доступа к данным на основе {@link org.hibernate.SessionFactory#getCurrentSession()}.

3. ДАО

Мы начнем с базового DAO – абстрактного, параметризованного DAO , который поддерживает общие общие операции и который мы можем расширить для каждой сущности:

public abstract class AbstractHibernateDAO< T extends Serializable >{
   private Class< T > clazz;

   @Autowired
   private SessionFactory sessionFactory;

   public void setClazz(Class< T > clazzToSet) {
      clazz = clazzToSet;
   }

   public T findOne(long id) {
      return (T) getCurrentSession().get( clazz, id );
   }
   public List< T > findAll() {
      return getCurrentSession()
       .createQuery( "from " + clazz.getName() ).list();
   }

   public void save(T entity) {
      getCurrentSession().persist( entity );
   }

   public T update(T entity) {
      return (T) getCurrentSession().merge( entity );
   }

   public void delete(T entity) {
      getCurrentSession().delete( entity );
   }
   public void deleteById(long id) {
      final T entity = findOne( id);
      delete( entity );
   }

   protected final Session getCurrentSession(){
      return sessionFactory.getCurrentSession();
   }
}

Здесь интересны несколько аспектов – как уже обсуждалось, абстрактный DAO не расширяет какой-либо шаблон Spring (например, HibernateTemplate ). Вместо этого Hibernate SessionFactory вводится непосредственно в DAO и будет играть роль основного API Hibernate через контекстный Сеанс , который он предоставляет:

this.SessionFactory.getCurrentSession();

Кроме того, обратите внимание, что конструктор получает Класс сущности в качестве параметра, который будет использоваться в универсальных операциях.

Теперь давайте рассмотрим пример реализации этого DAO для сущности Foo :

@Repository
public class FooDAO extends AbstractHibernateDAO< Foo > implements IFooDAO{

   public FooDAO(){
      setClazz(Foo.class );
   }
}

4. Заключение

В этой статье рассматривалась конфигурация и реализация уровня персистентности с помощью Hibernate и Spring.

Были обсуждены причины прекращения использования шаблонов для уровня DAO, а также возможные подводные камни настройки Spring для управления транзакциями и сеансом гибернации. Конечным результатом является легкая, чистая реализация DAO, практически не зависящая от Spring во время компиляции.

Реализацию этого простого проекта можно найти в проекте github .