Implémentation des DAO
JpaDaoSupport et JpaTemplate
Une première solution consistait à créer une classe DAO qui hérite de la classe JpaDaoSupport
de Spring.
Cette solution a disparu depuis Spring Framework 4.
Ecrire des DAO "Plain JPA"
La seconde solution consiste à écrire des DAO qui n’utilisent pas les classes Spring. Cette approche est intéressante car d’une part, elle semblera plus naturelle à un développeur JPA, et d’autre part, elle permet la configuration par annotation.
Avec cette solution, Spring injecte directement une instance "entity manager" dans notre DAO en exploitant l’annotation JPA @PersistenceContext
.
@Repository
public class ProductDao {
@PersistenceContext
private EntityManager em;
public List<Product> findByTitleLike(String title) {
return em.createQuery(
"select p from Product as p where p.title like :title",
Product.class)
.setParameter("title", title + '%')
.getResultList();
}
...
}
|
Déclarer l’entity manager factory
Pour déclarer l’entity manager factory, il faut d’abord considérer l’environnement d’exécution de notre code, à savoir :
-
Application standalone (cas d’une application Spring Boot, batch, test JUnit,…)
-
Serveur Tomcat
-
Serveur Java EE / Jakarta EE (Glassfish, JBoss / WildFly,…)
Cas d’une application standalone
Caractéristiques de l’environnement
-
La connexion n’est pas gérée nativement par un pool : d’où l’utilisation du bean
dataSource
de typeDataSource
-
Il n’existe pas nativement un conteneur JPA, permettant entre autres d’instancier l’entity manager factory : d’où le bean de type
LocalContainerEntityManagerFactoryBean
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee
https://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="info.jtips.spring"/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/jtips"/>
<property name="username" value="jtips" />
<property name="password" value="jtipspwd" />
</bean>
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
Application Tomcat
Caractéristiques de l’environnement :
-
La connexion est gérée par un pool de connexion déclaré sous Tomcat : d’où la récupération du bean
dataSource
par lookup JNDI. -
Il n’existe pas nativement un conteneur JPA, permettant entre autres d’instancier l’entity manager factory : d’où le bean de type
LocalContainerEntityManagerFactoryBean
.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee
https://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="info.jtips.spring"/>
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/LibrairieDS"/>
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
Application Java EE / Jakarta EE
Caractéristiques de l’environnement :
-
La connexion est gérée par un pool de connexion déclaré sous le serveur d’application : d’où la récupération du bean
dataSource
par lookup JNDI. -
Le serveur intègre nativement un conteneur JPA permettant l’instanciation de l’entity manager factory : on ne déclare donc pas l’entity manager factory avec Spring.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee
https://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="info.jtips.spring"/>
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/LibrairieDS"/>
</beans>
Configuration JPA
Il s’agit de renseigner le fichier persistence.xml placé dans le répertoire META-INF de l’archive de déploiement. Encore une fois, la configuration dépend de l’environnement d’exécution.
Cas d’une application standalone
Cet environnement d’exécution ne fournit pas de gestionnaire transationnel JTA[3].
On positionne donc l’attribut transation-type
à RESOURCE_LOCAL
.
La data source est pour sa part spécifiée dans la configuration Spring.
Par ailleurs, comme on utilise un conteneur Spring / JPA (le bean LocalContainerEntityManagerFactoryBean
), il faut préciser l’implémentation JPA à utiliser via l’élément provider
.
<persistence>
<persistence-unit name="jtips" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
</persistence-unit>
</persistence>
Application Tomcat
La configuration est identique au cas d’une application standalone.
<persistence>
<persistence-unit name="jtips" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
</persistence-unit>
</persistence>
Application Java EE / Jakarta EE
Les serveurs d’application Java EE fournissent un gestionnaire transationnel de type JTA.
On positionne donc l’attribut transation-type
à JTA
et on utilise l’élément jta-data-source
pour déclarer la data source.
Par ailleurs, les serveurs Java EE sont livrés avec une implémentation JPA.
Il n’est donc pas nécessaire de spécifier le provider JPA.
<persistence>
<persistence-unit name="jtips" transaction-type="JTA">
<jta-data-source>java:/jdbc/LibrairieDS</jta-data-source>
</persistence-unit>
</persistence>
Références
-
Exemples de code, avec Spring 5.3, Spring Boot 2.6 et Hibernate 5.6