Developpez.com - Java
X

Choisissez d'abord la catégorieensuite la rubrique :

logo
Sommaire > Accès aux données
        Comment intégrer Toplink et Spring ?
        Comment intégrer JPA et Spring ?

rechercher
precedent    sommaire       telechargermiroir



Comment intégrer JPA et Spring ?
auteurs : Righetto Dominique, djo.mos
Voici les déclarations à effectuer pour intégrer JPA et Spring (cet exemple se base sur l'utilisation de l'implémentation Oracle Toplink de JPA) :

Etape 1 : Déclaration dans le contexte Spring des dépendances JPA

Activation du tissage lors du runtime pour le contexte Spring afin que tous les beans implémentant l'interface "LoadTimeWeaverAware" (comme le bean LocalContainerEntityManagerFactoryBean) reçoivent une référence vers le tisseur (cf documentation Spring pour plus de précisions).

Remarque, le load time weaving n'est nécessaire qu'avec l'implémentation Toplink

<context:load-time-weaver />
Déclaration du "PersistenceUnitManager" permettant de personnaliser la sélection des unités de persistance et des sources de données.
(Cette étape n'est pas obligatoire )

	<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
		<!-- On spécifie ici les lieux  trouver les fichiers de persistence -->
		<property name="persistenceXmlLocations">
			<list>
				<value>classpath*:META-INF/persistence.xml</value>
			</list>
		</property>
		<!-- On spécifie ici les sources de données à utiliser, locale ou distante -->
		<property name="dataSources">
			<map>
				<entry key="localDataSource" value-ref="dataSource" />
				<!--<entry key="remoteDataSource" value-ref="remote-db" />-->
			</map>
		</property>
		<!-- On spécifie ici la sources de données par défaut si aucune source de données n'est disponible -->
		<property name="defaultDataSource" ref="dataSource" />
	</bean>
Déclaration de l' "EntityManagerFactory" permettant de fournir les instances des gestionnaires d'entités :

	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
		p:dataSource-ref="dataSource"
		p:persistenceUnitManager-ref="persistenceUnitManager">
		<!-- On spécifie ici l'adaptateur Spring pour l''implémentation JPA utilisée -->
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter" p:databasePlatform="oracle.toplink.essentials.platform.database.oracle.OraclePlatform"
				p:showSql="false" />
		</property>
		<!-- On spécifie ici le tisseur utilisée pour la modification du ByteCode, cf documentation de Spring pour plus de précisions -->
		<property name="loadTimeWeaver">
			<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
		</property>
		<!-- On spécifie ici le dialecte utilisé en fonction de l'implémentation JPA utilisée -->
		<property name="jpaDialect">
			<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
		</property>
	</bean>
Déclaration du "TransactionManager" qui est le gestionnaire de transactions

 
<bean id="txManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
		p:entityManagerFactory-ref="entityManagerFactory">
		<!-- On spécifie ici le dialecte utilisé en fonction de l' implémentation JPA utilisée -->
	<property name="jpaDialect">
                   <bean class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
	</property>
</bean>
Activation de la prise en compte des annotations de type @Required,@Autowired,@PostConstruct,@PreDestroy,@Resource,@PersistenceContext,@PersistenceUnit :

<context:annotation-config />
Déclaration d'un traducteur d'exception :

	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
Etape 2 : Implémentation d'une classe utilisant JPA

Chaque classe qui désire utiliser JPA pour accéder aux données peut :

  • Soit hériter de la classe "org.springframework.orm.jpa.support.JpaDaoSupport"
  • Soit se faire injecter un attribut de type "org.springframework.orm.jpa.JpaTemplate"
Dans le cas de l'héritage voici le type de déclaration à effectuer pour déclarer la classe (dépendance sur l' "EntityManagerFactory")

	<bean id="myDao" class="com.drighetto.springjpa.dao.impl.DaoJpaImpl"
		p:entityManagerFactory-ref="entityManagerFactory" />
Note : Pour le moment l'utilisation de JPA avec Spring ne supporte que l'isolation par défaut pour l'isolation des transactions... Dans la classe org.springframework.orm.jpa.DefaultJpaDialect (la classe "org.springframework.orm.jpa.vendor.TopLinkJpaDialect" hérite de cette classe) dans la méthode beginTransaction() une vérification est faite sur l'isolation placée et si celle-ci n'est pas placée à défaut alors l'exception suivante est levée "Standard JPA does not support custom isolation levels - use a special JpaDialect for your JPA implementation".

Voici le fichier de contexte dans son ensemble :


 
<?xml version="1.0" encoding="UTF-8"?>
<!--
	********************************************
	Application context for the project
	********************************************	
-->
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
			http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
 
 
 
 
	<!-- ========================= RESOURCE DEFINITIONS ========================= -->
 
	<!--
		Activates a load-time weaver for the context. Any bean within the context that
		implements LoadTimeWeaverAware (such as LocalContainerEntityManagerFactoryBean)
		will receive a reference to the autodetected load-time weaver.
	-->
	<context:load-time-weaver />
 
	<!-- DataSource -->
	<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
		p:driverClassName="oracle.jdbc.driver.OracleDriver"
		p:url="jdbc:oracle:thin:@localhost:1521:xe" p:username="MyTestUser"
		p:password="MyTestUser" />
 
	<!-- JNDI DataSource for JEE environments -->
	<!--
		<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
	-->
 
	<!-- JPA PersistenceUnitManager used to customize the selection of the persistence unit and the datasources -->
	<bean id="persistenceUnitManager"
		class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
		<!-- Multiple value can be specified here -->
		<property name="persistenceXmlLocations">
			<list>
				<value>classpath*:META-INF/persistence.xml</value>
			</list>
		</property>
		<property name="dataSources">
			<map>
				<entry key="localDataSource" value-ref="dataSource" />
				<!--<entry key="remoteDataSource" value-ref="remote-db" />-->
			</map>
		</property>
		<!-- if no datasource is specified, use this one -->
		<property name="defaultDataSource" ref="dataSource" />
	</bean>
 
	<!-- JPA EntityManagerFactory -->
	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
		p:dataSource-ref="dataSource"
		p:persistenceUnitManager-ref="persistenceUnitManager">
		<property name="jpaVendorAdapter">
			<bean
				class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter"
				p:databasePlatform="oracle.toplink.essentials.platform.database.oracle.OraclePlatform"
				p:showSql="false" />
		</property>
		<property name="loadTimeWeaver">
			<bean
				class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
		</property>
		<property name="jpaDialect">
			<bean
				class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
		</property>
	</bean>
 
	<!-- Transaction manager for a single JPA EntityManagerFactory (alternative to JTA) -->
	<bean id="txManager"
		class="org.springframework.orm.jpa.JpaTransactionManager"
		p:entityManagerFactory-ref="entityManagerFactory">
		<property name="jpaDialect">
			<bean
				class="org.springframework.orm.jpa.vendor.TopLinkJpaDialect" />
		</property>
	</bean>
 
 
 
 
	<!-- ========================= CONFIG DEFINITIONS ========================= -->
 
	<!--
		Activates various annotations to be detected in bean classes: Spring's
		@Required and @Autowired, as well as JSR 250''s @PostConstruct,
		@PreDestroy and @Resource (if available) and JPA's @PersistenceContext
		and @PersistenceUnit (if available).
	-->
	<context:annotation-config />
 
	<!-- Exception translation bean post processor -->
	<bean
		class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
 
 
 
 
	<!-- ================================== TRANSACTIONS DEFINITIONS ================================== -->
	<!-- For the moment JPA only support ISOLATION_DEFAULT for the transaction isolation -->
 
	<!-- Define pointcut for txAdvices -->
	<aop:config>
		<!-- DAO Layer -->
		<aop:advisor advice-ref="txAdviceDao"
			pointcut="execution(* com.drighetto.springjpa.dao.impl.*.*(..))" />
		<!-- Service Layer -->
		<aop:advisor advice-ref="txAdviceService"
			pointcut="execution(* com.drighetto.springjpa.services.*.*(..))" />
	</aop:config>
 
	<!-- the transactional advice for DAO layer -->
	<tx:advice id="txAdviceDao" transaction-manager="txManager">
		<!-- the transactional semantics... -->
		<tx:attributes>
			<!-- Read methods don't use a transaction -->
			<tx:method name="read*" propagation="SUPPORTS"
				read-only="true" />
			<!-- Exclude Getter/Setter -->
			<tx:method name="set*" propagation="SUPPORTS"
				read-only="true" />
			<tx:method name="get*" propagation="SUPPORTS"
				read-only="true" />
			<!-- All others methods must use a existing transaction -->
			<tx:method name="*" isolation="DEFAULT" timeout="10"
				propagation="MANDATORY" read-only="false"
				rollback-for="org.springframework.dao.DataAccessException" />
		</tx:attributes>
	</tx:advice>
 
	<!-- the transactional advice for Service layer -->
	<tx:advice id="txAdviceService" transaction-manager="txManager">
		<!-- the transactional semantics... -->
		<tx:attributes>
			<!-- Read methods don't use a transaction -->
			<tx:method name="display*" propagation="SUPPORTS"
				read-only="true" />
			<!-- Exclude Getter/Setter -->
			<tx:method name="set*" propagation="SUPPORTS"
				read-only="true" />
			<tx:method name="get*" propagation="SUPPORTS"
				read-only="true" />
			<!-- All others methods create a transaction -->
			<tx:method name="*" isolation="DEFAULT" timeout="10"
				propagation="REQUIRES_NEW" read-only="false"
				rollback-for="org.springframework.dao.DataAccessException" />
		</tx:attributes>
	</tx:advice>
 
 
 
 
	<!-- ================================== BEANS DEFINITIONS ================================== -->
 
	<!-- DAO -->
	<bean id="myDao" class="com.drighetto.springjpa.dao.impl.DaoJpaImpl"
		p:entityManagerFactory-ref="entityManagerFactory" />
 
	<!-- Service -->
	<bean id="myService"
		class="com.drighetto.springjpa.services.Processor"
		p:myDao-ref="myDao" />
 
</beans>
 
lien : en Section JPA sur la documentation officielle

rechercher
precedent    sommaire       telechargermiroir

Consultez les autres F.A.Q's


Valid XHTML 1.1!Valid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2004 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Responsables bénévoles de la rubrique Java : Mickael Baron - Robin56 -