DAO с JPA и Spring

1. Общ преглед

Тази статия ще покаже как да внедрите DAO с Spring и JPA . За основната JPA конфигурация вижте статията за JPA с Spring.

2. Няма повече пролетни шаблони

Започвайки с Spring 3.1, JpaTemplate и съответната JpaDaoSupport са оттеглени в полза на използването на собствения API за устойчивост на Java.

Също така и двата класа са подходящи само за JPA 1 (от JpaTemplate javadoc):

Обърнете внимание, че този клас не е надстроен до JPA 2.0 и никога няма.

В резултат на това сега е най-добрата практика да се използва API за устойчивост на Java директно вместо JpaTemplate .

2.1. Превод на изключение без шаблон

Една от отговорностите на JpaTemplate беше преводът на изключенията - превод на изключенията от ниско ниво в по-високо ниво, общи изключения на Spring.

Без шаблона, преводът на изключения все още е разрешен и напълно функционален за всички DAO, коментирани с @Repository . Spring реализира това с постпроцесор на боб, който ще съветва всички зърна @Repository с всички PersistenceExceptionTranslator, намерени в контейнера.

Също така е важно да се отбележи, че механизмът за превод на изключения използва прокси - за да може Spring да създава прокси около DAO класовете, те не трябва да бъдат обявявани за окончателни .

3. DAO

Първо, ще приложим базовия слой за всички DAO - абстрактен клас, използващ генерични продукти и проектиран да бъде разширен:

public abstract class AbstractJpaDAO { private Class clazz; @PersistenceContext EntityManager entityManager; public final void setClazz( Class clazzToSet ){ this.clazz = clazzToSet; } public T findOne( long id ){ return entityManager.find( clazz, id ); } public List 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 ); } }

Основният интересен аспект тук е начинът на инжектиране на EntityManager - използвайки стандартната анотация @PersistenceContext . Под капака това се обработва от PersistenceAnnotationBeanPostProcessor - който обработва анотацията, извлича JPA мениджъра на обекта от съдържанието и го инжектира.

Постоянният процесор за постоянство се създава изрично чрез дефинирането му в конфигурацията или автоматично, чрез дефиниране на context: annotation-config или context: component-scan в конфигурацията на пространството от имена.

Също така имайте предвид, че класът на обекта се предава в конструктора, за да се използва в общите операции:

@Repository public class FooDAO extends AbstractJPADAO implements IFooDAO{ public FooDAO(){ setClazz(Foo.class ); } }

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

Този урок илюстрира как да настроите DAO слой с Spring и JPA , като използвате XML и Java базирана конфигурация. Също така обсъдихме защо да не използваме JpaTemplate и как да го заменим с EntityManager . Крайният резултат е леко, изчистено изпълнение на DAO, почти без разчитане на времето за компилация на Spring.

Изпълнението на този прост проект може да се намери в проекта GitHub - това е проект, базиран на Maven, така че трябва да е лесно да се импортира и да се изпълнява както е.