JPA 2.0 sous Websphere 7

Websphere 7 implémente la version 1.x de la spécification JPA. Afin d'utiliser la version 2.0, IBM recommande d'acheter le Feature Pack "OSGI & JPA 2.0" ou bien de migrer vers Websphere 8 . A-t-on d'autres choix?

Dans sa version 2.0, la spécification JPA (Java Persistence API) a été améliorée et a intégré de nouvelles fonctionnalités telles que les APIs Cache et Criteria. Les principaux frameworks d'ORM Java implémentent cette version de la  spécification et sa mise en place en dehors d'un conteneur JEE  est facilement réalisable à l'aide d'un conteneur léger comme SPRING.

Ici, on s'intéresse à la mise en place de JPA2.0 dans le serveur IBM Websphere Applicatio Server 7 (abrégé Websphere7 ).

Websphere7 supporte la verion 1.x de JPA. Il embarque la version 1.2.x d'OpenJPA. Afin d'utiliser la version 2.0 de JPA, IBM recommande de :
   * Migrer vers Websphere8 : cette version est sortie en Juin 2011 ou bien
   * Acheter le "OSGI & JPA 2.0 Feature Pack" : une extension proposée par IBM permettant de développer et déployer des applications utilisant OSGI et/ou JPA 2.0


Discussion des solutions
Migrer vers Websphere 8 n'est pas toujours possible pour des raisons de :
  - Coût
  - Planning (migration prévue mais pas imminente)

La deuxième solution consistant  à acheter le Feature Pack "OSGI & JPA 2.0" n'est pas non plus toujours possible parce que justement on prévoit de migrer vers Websphere8 et par conséquent il vaut mieux économiser le prix du Feature Pack.


Alternative
Consiste à embarquer l'API JPA2.0 et son implémentation ( Hibernate3.6.x  par exemple) dans l'application. Cette solution peut être résumée en trois étapes :


1. L'application doit être configurée pour s'exécuter dans le mode de classloading PARENT_LAST


Webspehere 7 fournit deux mode de classloading :
  * PARENT_FIRST : Une classe requise par l'application est recherchée d'abord dans les librairies du serveur et si elle y est introuvable alors elle est recherchée dans les librairies de l'application (répertoire lib d'un EAR, WEB-INF/lib d'un WAR)
  * PRENT_LAST : l'inverse du mode PARENT_FIRST

Dans le mode PARENT_LAST, les classes d'API et d'implémentation de JPA 2.0 vont être recherchées dans les librairies de l'application ce qui évite de charger celles de Websphere ( qui ne sont pas compatibles JPA 2.0)


2. Le fichier persistence.xml doit être déplacé ou bien renommé


La balise racine de ce fichier comporte un attribut version qui doit être égal à 2.0 si l'on désire utiliser JPA2.0. Supposons que ce soit le cas.

La spécification JPA dicte au conteneurs JEE de chercher ce fichier dans META-INF/persistence.xml. Au démarrage de l'application sous WAS7, ce dernier va :
   * chercher META-INF/persistence.xml
   * parser le fichier
   * lever une exception de validation XML disant que l'attribut version comporte une valeur invalide

C'est pour cette raison qu'il est obligatoire de renommer ce fichier ( ou bien le déplacer vers un endroit accessible depuis le classpath) afin de le rendre invisible aux yeux de Websphere7


3. Démarrage manuel de la persistance

Une fois l'étape précédente accomplie, il faut trouver le moyen de soumettre le fichier de persistance à un fournisseur JPA. Cela peut être réalisé de deux manière : 
   * Soit programmatiquement en manipulant les APIs de bas niveau de JPA
   * Ou bien se servir de SPRING

Spring offre l'abstraction LocalContainerEntityManagerFactoryBean qui permet de démarrer JPA en :
   * parsant un fichier persistence.xml fourni
   * Construisant un objet PersistentUnitInfo  et en passant ce dernier au fournisseur d'implémentation (Hibernate3.6.x par exemple)

L'extrait suivant montre comment soumettre le fichier de persistance en supposant que l'on ait renommé le fichier de persistance en was7_jpa2_persistence.xml.

<bean id="localContainerEntityManagerFactory"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

   <property name="persistenceXmlLocation"
                      value="classpath:META-INF/was7_jpa2_persistence.xml" />
        <!-- Le reste de la configuration -->
        ....
</bean>

Conclusion

Sous certaines conditions de classloading et de nommage de fichier, JPA2.0 peut être utilisée sous Websphere7.

liens :
  1. Spring ORM 
  2. Configuration du mode de classloading d'une application WEB sous Websphere7