Integración de Spring y JPA
- Área: Construcción de Aplicaciones por Capas
- Grupo: Java
- Carácter del recurso: Recomendado
- Tecnologías: Spring, JPA
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
Código | Título | Tipo | Carácter | |
---|---|---|---|---|
LIBP-0050 | Integración Spring - JPA | Libro de pautas | Directriz | Recomendada |