DAO с JPA и весной
1. обзор
Эта статья покажет, какimplement the DAO with Spring and JPA. Для базовой конфигурации JPA см.the article about JPA с Spring.
2. Больше никаких шаблонов Spring
Начиная с Spring 3.1,JpaTemplate и соответствующийJpaDaoSupporthave been устарели в пользу использования собственного Java Persistence API.
Кроме того, оба этих класса актуальны только для JPA 1 (из javadocJpaTemplate):
Обратите внимание, что этот класс не был обновлен до JPA 2.0 и никогда не будет обновлен.
Как следствие, теперь рекомендуется использоватьuse the Java Persistence API directly вместоJpaTemplate.
2.1. Исключительный перевод без шаблона
Одной из обязанностейJpaTemplate былexception translation - перевод исключений низкого уровня в общие исключения Spring более высокого уровня.
Без шаблонаexception translation is still enabled and fully functional для всех DAO, аннотированных@Repository. Spring реализует это с помощью постпроцессора bean, который сообщит всем bean-компонентам@Repository всеPersistenceExceptionTranslator, найденные в контейнере.
Также важно отметить, чтоthe exception translation mechanism uses proxies - чтобы Spring мог создавать прокси вокруг классов DAO, их нельзя объявлятьfinal.
3. DAO
Во-первых, мы реализуем базовый уровень для всех DAO - абстрактный класс, использующий дженерики и предназначенный для расширения:
public abstract class AbstractJpaDAO< T extends Serializable > {
private Class< T > clazz;
@PersistenceContext
EntityManager entityManager;
public final void setClazz( Class< T > clazzToSet ){
this.clazz = clazzToSet;
}
public T findOne( long id ){
return entityManager.find( clazz, id );
}
public List< T > findAll(){
return entityManager.createQuery( "from " + clazz.getName() )
.getResultList();
}
public void create( T entity ){
entityManager.persist( entity );
}
public T update( T entity ){
return entityManager.merge( entity );
}
public void delete( T entity ){
entityManager.remove( entity );
}
public void deleteById( long entityId ){
T entity = findOne( entityId );
delete( entity );
}
}
Главный интересный аспект здесь - способthe EntityManager is injected - с использованием стандартной аннотации@PersistenceContext. Под капотом этим занимаетсяPersistenceAnnotationBeanPostProcessor, который обрабатывает аннотацию, извлекает диспетчер сущностей JPA из контейнеров и внедряет его.
Постпроцессор постоянства создается либо явно, определяя его в конфигурации, либо автоматически, определяяcontext:annotation-config илиcontext:component-scan в конфигурации пространства имен.
Также обратите внимание, что объектClass передается в конструктор для использования в общих операциях:
@Repository
public class FooDAO extends AbstractJPADAO< Foo > implements IFooDAO{
public FooDAO(){
setClazz(Foo.class );
}
}
4. Заключение
В этом руководстве проиллюстрированhow to set up a DAO layer with Spring and JPA с использованием конфигурации на основе XML и Java. Мы также обсудили, почему не использоватьJpaTemplate и как заменить его наEntityManager. Конечный результат - легкая, чистая реализация DAO, практически не зависящая от Spring во время компиляции.
Реализацию этого простого проекта можно найти вthe GitHub project - это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.