Перейти к основному содержимому

DAO с Spring и Hibernate

· 3 мин. чтения

1. Обзор

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

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

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

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

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

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

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

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

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

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

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

3. ДАО

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

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

@Autowired
protected SessionFactory sessionFactory;

public final void setClazz(final Class<T> clazzToSet) {
clazz = Preconditions.checkNotNull(clazzToSet);
}

// API
public T findOne(final long id) {
return (T) getCurrentSession().get(clazz, id);
}

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

public T create(final T entity) {
Preconditions.checkNotNull(entity);
getCurrentSession().saveOrUpdate(entity);
return entity;
}

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

public void delete(final T entity) {
Preconditions.checkNotNull(entity);
getCurrentSession().delete(entity);
}

public void deleteById(final long entityId) {
final T entity = findOne(entityId);
Preconditions.checkState(entity != null);
delete(entity);
}

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

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

this.sessionFactory.getCurrentSession();

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

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

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

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

4. Вывод

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

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

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