mardi 5 avril 2011

Spring comme provider JPA au sein d’un conteneur EE5

Notamment dans JBoss 5, cela pose un problème. En effet, le conteneur va scanner l’ensemble des librairies pour trouver le ou les fichiers de définitions des “persistence units” (META-INF/persistence.xml). Or, lorsque l’on souhaite que ce soit Spring qui gère la création de l’”EntityManagerFactory”, ce fichier de définition peut être très succinct :
<persistence xmlns=&<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
    version="2.0">
 
 <persistence-unit name="myPersistenceUnit">
  <class>model.MyEntityClass</class>  
 </persistence-unit>
  
</persistence>
Cette description ne permettra pas au conteneur EE5 de démarrer cette “persistence unit” en l’absence de source de données.
Par exemple, sous JBoss 5 le serveur indiquera qu’une spécification n’est pas respectée :

Specification violation [EJB3 JPA 6.2.1.2] - You have not defined a non-jta-data-source for a RESOURCE_LOCAL enabled persistence context named: myPersistenceUnit

La solution consiste a renommer le fichier persistence.xml de telle sorte qu’il ne soit pas pris en compte par le serveur (exemple : jpa-persistence.xml).
Mais cela ne suffit pas : le conteneur va aussi scanner toutes les classes à la recherche de l’annotation  @PersistenceContext et sera incapable de charger la “persistence-unit” correspondante.
Là, l’attribut metadata-complete de l’élément web-app du fichier de configuration web.xml permet de préciser au conteneur de ne pas prendre en compte les annotations Java EE parce qu'elles sont gérées pas un autre mécanisme (Spring en l’occurrence dans notre cas).
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5" metadata-complete="true">
</web-app>