lundi 25 février 2013

Génération Schéma Hibernate Annotation avec JNDI

Hiers, je suis tombé sur un os :
Pour le site de calcul d'ensoleillement sur www.heliorama.com, la gestion de la persistance objet est faite par Hibernate, avec une configuration par Annotation et la définition de la datasource en JNDI.

La méthode classique pour générer un schéma DDL à partir de la config annotation est d'utiliser la tâche ant hibernatetool, de cette façon (QUI NE FONCTIONNE PAS SI LA DATASOURCE EST EN JNDI):


<hibernatetool destdir="./generated">
 <classpath>
  <path location="." />
  <path location="../build/classes" />
 </classpath>
 <annotationconfiguration configurationfile="../WebContent/WEB-INF/hibernate.cfg.xml"/>
 <hbm2ddl export="false" outputfilename="sql.ddl"/>
</hibernatetool>

A ce propos, il assez sioux de faire fonctionner cette tâche, étant donné qu'il faut récupérer tout les jar nécessaires. Pour ma part, j'ai décidé d'allez assez vite en ajoutant tout les jar du plug-in hibenate-tool eclipse (plugins/org.jboss.tools.hibernate4_0_3.5.1.v20130102-1835-H100-Final) et tous les jar de ma webapp.

On défini un classpath de cette façon :


<path id="toolslib">
<fileset dir="lib" includes="**/*.jar"/> <!-- copie du plug-in hibernate-tool dans un répertoire lib au même niveau que le build.xml -->
<fileset dir="../WebContent/WEB-INF/lib" includes="**/*.jar"/> <!-- webapp -->
</path>

Puis on l'utilise dans une taskdef :

<taskdef name="hibernatetool"
         classname="org.hibernate.tool.ant.HibernateToolTask"
         classpathref="toolslib" />

Ce qui donne le fichier de build ant :

<project name="MyProject" basedir="." default="default">
<path id="toolslib">
<fileset dir="lib" includes="**/*.jar"/>
<fileset dir="../WebContent/WEB-INF/lib" includes="**/*.jar"/>
</path>

<taskdef name="hibernatetool"
         classname="org.hibernate.tool.ant.HibernateToolTask"
         classpathref="toolslib" />

<target name="default">
<hibernatetool destdir="./generated">
 <classpath>
  <path location="." />
  <path location="../build/classes" />
 </classpath>
 <annotationconfiguration configurationfile="../WebContent/WEB-INF/hibernate.cfg.xml"/>
 <hbm2ddl export="false" outputfilename="sql.ddl"/>
</hibernatetool>
</target>
</project>

JNDI 

Lorsque la configuration de la connexion à la base de donnée est définie par JNDI, il est évident que cela ne peut pas fonctionner. Pourquoi ? Car un build ant n'a pas de context JNDI défini et encore moins celui de tomcat (ou autre) où est définie notre datasource.

La solution est de faire la génération de manière programatique :


// Get de MySQL Dialect
Properties props = new Properties();
props.put(Environment.DIALECT , "org.hibernate.dialect.MySQLDialect");
props.put(Environment.DEFAULT_SCHEMA, "heliorama");
Dialect dialect = Dialect.getDialect(props);

// Configure Hibernate
File configFile = new File("WebContent/WEB-INF/hibernate.cfg.xml");
Configuration configure = new Configuration().configure(configFile).setProperties(props);

// Generate Drop
String[] sqls  = configure.generateDropSchemaScript(dialect);
for(String s : sqls){
System.out.println(s + ";");
}

// Generate schema
sqls  = configure.generateSchemaCreationScript(dialect);
for(String s : sqls){
System.out.println(s + ";");
}












Aucun commentaire:

Enregistrer un commentaire