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 .