FAQ SpringConsultez toutes les FAQ

Nombre d'auteurs : 5, nombre de questions : 41, dernière mise à jour : 24 avril 2008  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.

Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.


Sommaire Accès aux données (2)
précédent sommaire
 

Pour intégrer Oracle Toplink et Spring il faut déclarer un bean « sessionFactory » dans lequel on va préciser :

  • l'endroit où se trouve le fichier de session qui contient lui-même l'endroit où se trouve le descripteur de mapping ;
  • la source de données ;
  • le logger.

Code xml : Sélectionner tout
1
2
3
4
5
6
7
<bean id="sessionFactory" class="org.springframework.orm.toplink.LocalSessionFactoryBean"> 
		<property name="configLocation" value="toplink-sessions.xml"/> 
		<property name="dataSource" ref="dataSource"/> 
		<property name="sessionLog"> 
			<bean class="org.springframework.orm.toplink.support.CommonsLoggingSessionLog"/> 
		</property> 
</bean>
Dans cet exemple on indique que :

  • le fichier de session Toplink se trouve à la racine du classpath de l'application ;
  • la source de données est un bean déjà défini et nommé « dataSource » ;
  • le logger est CommonsLogging et il est géré par Spring.

Voici le contenu de mon fichier de session « toplink-sessions.xml » qui indique que le fichier de mapping « toplink-Mapping.xml » est lui aussi à la racine du classpath de l'application :

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
  
<?xml version="1.0" encoding="UTF-8"?> 
<toplink-sessions version="10g Release 3 (10.1.3.0.0)" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
   <session xsi:type="server-session"> 
      <name>Session</name> 
      <event-listener-classes/> 
      <primary-project xsi:type="xml">toplink-Mapping.xml</primary-project>       
   </session> 
</toplink-sessions>
Note : il faut enlever dans le fichier de mapping Toplink les informations de connexion à la base de données. En effet, Spring s'occupant de fournir la source de données (via le dataSource), il détecte un conflit et ne peut pas créer une instance de la sessionFactory.

Ensuite pour utiliser ce bean « sessionFactory », il suffit d'hériter de la classe « org.springframework.orm.toplink.support.TopLinkDaoSupport » et d'utiliser le ToplinkTemplate via « getTopLinkTemplate() » pour exécuter des traitements.

Code java : Sélectionner tout
1
2
3
public class MonDaoImpl extends TopLinkDaoSupport implements MonDao { 
//Placer les méthodes utilisant "getTopLinkTemplate()" ici... 
}
Sans oublier de configurer le bean correctement, en lui fournissant une instance de la sessionFactory :

Code xml : Sélectionner tout
1
2
3
<bean id="monDao" class="com.drighetto.dao.impl.MonDaoImpl"> 
	<property name="sessionFactory" ref="sessionFactory" /> 
</bean>

Mis à jour le 24 avril 2008 Righetto Dominique

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) :

Étape 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.

Code xml : Sélectionner tout
<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).

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	<bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"> 
		<!-- On spécifie ici les lieux où trouver les fichiers de persistance --> 
		<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 source 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 :

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	<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é 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

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
  
<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 :

Code xml : Sélectionner tout
<context:annotation-config />
Déclaration d'un traducteur d'exception :

Code xml : Sélectionner tout
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
Étape 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 ») :

Code xml : Sélectionner tout
1
2
	<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 généré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 :

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
  
<?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>

Mis à jour le 24 avril 2008 djo.mos Righetto Dominique

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire
 

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 © 2017 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 Spring : Mickael Baron - Robin56 -