Integración de Spring y JPA

RECU-0823 (Recurso Referencia)

Descripción

Configuración para integrar Spring con JPA

Spring JPA ofrece varios tipos de posibilidades para implementar el EntityManagerFactory de JPA. Dadas las características de los proyectos que se van a mantener en Spring, lo normal es hacerlo mediante LocalContainerEntityManagerFactoryBean.

LocalContainerEntityManagerFactoryBean da acceso completo a la configuración del EntityManagerFactory y es lo apropiado para entornos donde es requerido un afinamiento. Permite crear un PersistenceUnitInfo basado en el archivo de persistencia persistence.xml, supliendo la estrategia dataSourceLookup y especificando loadTimeWeaver. De esta manera se puede trabajar con DataSources fuera del JNDI . Un ejemplo de configuración sería la siguiente:

<beans>
       
 <bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="someDataSource"/>
  <property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
  </property>
 </bean>
 
</beans>

y un típico fichero de persistencia:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

  <persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
    <mapping-file>META-INF/orm.xml</mapping-file>
    <exclude-unlisted-classes/>
  </persistence-unit>

</persistence>

Esta es la opción configuración de JPA más potente, ya que permite la configuración local flexible en la aplicación. Es compatible con enlaces a los DataSource de JDBC existentes, soporta tanto transacciones locales como transacciones globales, etc. Sin embargo, también impone requisitos en el entorno de ejecución. Se debe tener en cuenta que esta opción puede entrar en conflicto con las capacidades integradas en un servidor Java EE 5. Así que cuando se ejecuta en un entorno de Java EE 5, es mejor considerar la posibilidad de obtener su EntityManagerFactory a través de JNDI.

Creación de DAOs: Soporte del JpaTemplate y JpaDaoSupport

Cada DAO basado en JPA, recibirá una inyección de dependencias a través de EntityManagerFactory. Tal DAO puede ser codificado siguiendo el plan de JPA y trabajar con el EntityManagerFactory determinado a través de JpaTemplate de Spring como en el ejemplo siguiente:

<beans>

  <bean id="myProductDao" class="product.ProductDaoImpl">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
  </bean>

</beans>
public class JpaProductDao implements ProductDao {
 
    private JpaTemplate jpaTemplate;

    public void setEntityManagerFactory(EntityManagerFactory emf) {
        this.jpaTemplate = new JpaTemplate(emf);
    }

    public Collection loadProductsByCategory(final String category) throws DataAccessException {
        return (Collection) this.jpaTemplate.execute(new JpaCallback() {
            public Object doInJpa(EntityManager em) throws PersistenceException {
                Query query = em.createQuery("from Product as p where p.category = :category");
                query.setParameter("category", category);
                List result = query.getResultList();
                // do some further processing with the result list
                return result;
            }
        });
    }
}

La aplicación JpaCallback permite cualquier tipo de acceso a datos en JPA. El JpaTemplate se asegurará de que debidamente el EntityManagers se abre y se cierra adecuadamente y automáticamente participa en las transacciones. Por otra parte, el JpaTemplate controla adecuadamente las excepciones, asegurando que los recursos se limpian y se deshacen las operaciones apropiadas.

Las plantillas de casos son "thread-safe y reutilizables y se pueden mantener como variable de instancia de la clase envolvente. Se debe tener en cuenta que JpaTemplate ofrece acciones de un solo paso, como buscar, cargar, fusión, etc., junto con métodos de conveniencia alternativa que puede sustituir a una implementación de devolución de llamada de línea.

Por otra parte, Spring ofrece una clase JpaDaoSupport que proporciona el get / set del EntityManagerFactory y getJpaTemplate () para ser utilizado por las subclases.

Manejo de las excepciones por Spring 

Si quiere trasladar el manejo de excepciones de JPA a Spring se puede realizar de forma sencilla. Solo resulta necesario introducir la anotación @Repository en la clases. De esta manera se informa al contenedor de Spring que esta clase es un repositorio de persistencia y necesita trasladar la excepción generada en ella. Para ello resulta necesario definir un bean como el siguiente:

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

Participación en el manejo de la transacción

Uno de los beneficios del manejo declarativo de transacciones por Spring es que nunca se tiene que hacer referencia a la estructura de la transacción dentro del código. Así, se puede manejar la participación en las transacciones de forma automática:

<bean  id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" />

<bean class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<tx:annotation-driven />

JpaTransactionManager es el responsable de crear apertura de transacciones en el EntityManager y enlazarla al hilo del contexto actual. La etiqueta <tx:annotation-driven /> le dice a Spring que debe de poner un aviso sobre cualquier método o clase que tenga la anotación @Transactional. De esta manera se puede escribir lógica sobre los DAOs sin tener que considerar la semántica transactional.

Contenidos relacionados

Pautas
Área: Desarrollo » Construcción de Aplicaciones por Capas » Java
Código Título Tipo Carácter
LIBP-0050 Integración Spring - JPA Libro de pautas Directriz Recomendada