lundi 4 mai 2009

JAVA JPA : problème de persistence.xml avec RAD

Lorsqu'on essaye d'intégrer JPA (Java Persistence API) dans un projet Web sous RAD (Rational Application Developper) 6 ou 7, j'ai remarqué un petit soucis à la configuration et au démarrage de l'application sur un serveur WebSphere 6.1 (je sais pas sur les versions suivantes ou précédentes). (RAD étant basé sur Eclipse peut être que ce problème se produit aussi sous Eclipse, à vérifier)

J'ai créé un fichier de configuration persistence.xml dans le répértoire META-INF (WebContent/META-INF sous RAD) comme le préconise la documentation de JPA (un petit tour sur le site officiel http://java.sun.com/javaee/overview/faq/persistence.jsp peut ne pas faire de mal !). Dans ce fichier, j'ai juste créé une unité de persistance car il en faut au moins une pour JPA :




Ma base de données contient une table Banque donc j'ai créé la classe Java correspondante à cette table, cette classe se nomme : test.struts2.helloworld.data.Banque (package+nom de la classe) :


package test.struts2.helloworld.data;
import java.sql.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Banque
{
@Id
@GeneratedValue
private Integer refbqe;

private String nombqe;
private String vilbqe;

public String getNombqe()
{
return nombqe;
}

public void setNombqe(String nombqe)
{
this.nombqe = nombqe;
}
public String getVilbqe()
{
return vilbqe;
}
public void setVilbqe(String vilbqe)
{
this.vilbqe = vilbqe;
}

public Banque()
{
}

public Integer getRefbqe()
{
return refbqe;
}

public void setRefbqe(Integer refbqe)
{ this.refbqe = refbqe;
}
}

Au démarrage de mon application, j'avais l'exception suivante :


Caused by: java.lang.NoClassDefFoundError: WEB-INF.classes.test.struts2.helloworld.data.Banque (wrong name: test/struts2/helloworld/data/Banque)
at java.lang.ClassLoader.defineClassImpl(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:228)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:148)
at com.ibm.ws.classloader.CompoundClassLoader._defineClass(CompoundClassLoader.java:562)
at com.ibm.ws.classloader.CompoundClassLoader.findClass(CompoundClassLoader.java:514)
at com.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:388)
at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
..etc


Tout me parait pourtant correct dans ma configuration et dans ma banque... Après m'être arraché les cheveux, je suis tombé sur un post (désolé j'ai perdu l'adresse) qui explique qu'en fait ce problème vient de RAD...

En effet, normalement JPA s'attends que persistence.xml soit, au déploiement de l'application sur le serveur Web, dans le répertoire WebContent/classes/META-INF/. JPA cherchera les classes mappant avec la base à partir du répertoire parent du répertoire de persistence.xml (c'est à dire WebContent/classes).

Mais voila, RAD au déploiement, ne créé pas le répertoire WebContent/classes/META-INF/ avec le fichier de configuration a l'intérieur, il le laisse dans WebContent/META-INF. Du coup, JPA cherche les classes mappant la base dans WebContent/ et non pas WebContent/classes d'où l'exception levée !!

Pour corriger cela, il faut un poil bidouiller :
-il faut créer un répertoire META-INF dans les sources et placer le persistence.xml dans ce répertoire
-supprimer le fichier WebContent/META-INF/persistence.xml
Au déploiement, RAD mettra bien persistence.xml dans WebContent/classes/META-INF !

Pour la 1ere partie, pour ceux qui ne savent pas faire, voici comment procéder :
-dans RAD, ouvrir son projet Web
-ouvrir la vue 'Navigateur' (menu Fenetre/Afficher la vue/Navigateur)
-créer un dossier META-INF (pas un package ni un dossier source mais un dossier tout simple) dans le dossier src/
-placer le fichier persistence.xml dans ce répertoire

Voila c'est tout simple !! Encore faut il le savoir !!

Aucun commentaire:

Enregistrer un commentaire