The DAO with JPA and Spring


1.概述

本文将展示如何使用Spring和JPA实现DAO。有关核心JPA配置,请参阅有关JPA with Spring 的文章。

2.No More Spring Templates

与Spring 3.1开始,JpaTemplate能够和相应的JpaDaoSupport 已经被弃用,取而代之的使用本地Java持久性API的。

此外,这两个类仅与JPA 1(来自JpaTemplate javadoc)相关:

Note that this class did not get upgraded to JPA 2.0 and never will.

因此,现在最好的做法是直接使用Java Persistence API而不是JpaTemplate。

2.1。没有模板的异常翻译

JpaTemplate的职责之一是异常转换 - 将低级异常转换为更高级别的通用Spring异常。

如果没有模板,则仍会启用异常转换,并且对于使用@Repository注释的所有DAO都可以完全正常运行。Spring使用bean后处理器实现它,它将使用在Container中找到的所有PersistenceExceptionTranslator建议所有@Repository bean 。

同样重要的是要注意异常转换机制使用代理 - 对于Spring来说,能够围绕DAO类创建代理,这些代理不能被声明为final。

3. DAO

首先,我们将为所有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 );
   }
}

这里的主要有趣的方面是这样的EntityManager的注入 -使用标准@PersistenceContext注解。在引擎盖下,这由PersistenceAnnotationBeanPostProcessor处理- 它处理注释,从包中检索JPA实体管理器并注入它。

持久性后处理器可以通过在配置中定义它来显式创建,也可以通过在命名空间配置中定义context:annotation-config或context:component-scan来自动创建。

另请注意,实体Class在构造函数中传递以在泛型操作中使用:

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

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