Question

J'utilise:

  • EJB3 / JPA (Hibernate)
  • MySQL 5

Je dois mettre en place un système pour aider les migrations de bases de données. A essayé d'utiliser LiquiBase mais il ne semble pas encore assez mature pour être utilisé avec Hibernate.

Ce que je voudrais faire est:

  • J'ai la version 1.0 de l'application dans la production
  • J'ai la version 2.0 de l'application développée et testée
  • Je veux mettre à jour la base de données de l'application dans la production sans perdre de données

En fait, je voudrais utiliser la nouvelle persistence.xml et la base de données de production pour être en mesure de générer le « delta » entre l'ancienne base de données et le nouveau. Je voudrais être en mesure de récupérer le code SQL qui est exécutée lorsque hbm2ddl est en mode « mise à jour ».

Ce code SQL sera modifié (baisse + create = renommer etc ...) pour éviter de perdre des données qui pourraient se produire avec hbm2ddl.auto=update.

Je suppose qu'il est possible parce que Hibernate lorsque le déploiement d'une nouvelle version avec hbm2ddl.auto=update. Mais je veux être en mesure de le faire dans une tâche Ant avec hibernatetool.

Je ne trouve pas beaucoup d'informations à ce sujet sur Internet, donc je me demande si quelqu'un a déjà fait quelque chose comme ça ici et me aider.

Je l'ai fait ce qui suit:

<hibernatetool destdir="${dist}">
            <!--
            <jdbcconfiguration propertyfile="hibtest.properties"></jdbcconfiguration>
            -->
            <jpaconfiguration persistenceunit="server-pu" />
            <classpath>
                <fileset dir="${core.lib.server}" includes="*.jar" />
                <fileset dir="${core.lib.runtime}" includes="*.jar" />
                <fileset dir="${core.lib.build}" includes="*.jar" />
                <pathelement location="${core.class}" />
                <pathelement location="${core.etc}" />
            </classpath>
            <hbm2ddl outputfilename="schema-delta.sql" format="true"
                export="false" update="true" />
</hibernatetool>

Je ne sais pas vraiment comment faire, j'ai pu obtenir le fichier sql de création, mais je veux juste le delta. Je dois mettre à jour = « true »? Puis-je utiliser la jpaconfig avec l'unité de persistance en dehors du serveur d'applications (les paramètres db sont fixés sur JNDI sur Glassfish ressource). (Essayé et il ne peut pas trouver le db)

J'ai essayé aussi avec <jdbcconfiguration propertyfile="hibtest.properties"></jdbcconfiguration> ou la définition des propriétés de la base de données en persistence.xml au lieu d'utiliser des ressources JNDI.

Je suis l'erreur suivante:

BUILD FAILED
/home/slorber/workspace/build/build.xml:899: org.hibernate.exception.JDBCConnectionException: Getting database metadata
    at org.hibernate.tool.ant.HibernateToolTask.reportException(HibernateToolTask.java:226)
    at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:189)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:357)
    at org.apache.tools.ant.Target.performTasks(Target.java:385)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1298)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
    at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
    at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
Caused by: org.hibernate.exception.JDBCConnectionException: Getting database metadata
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:97)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getMetaData(AbstractMetaDataDialect.java:64)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.caseForSearch(AbstractMetaDataDialect.java:163)
    at org.hibernate.cfg.reveng.dialect.JDBCMetaDataDialect.getTables(JDBCMetaDataDialect.java:22)
    at org.hibernate.cfg.reveng.JDBCReader.processTables(JDBCReader.java:476)
    at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:74)
    at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:860)
    at org.hibernate.cfg.JDBCBinder.readDatabaseSchema(JDBCBinder.java:115)
    at org.hibernate.cfg.JDBCBinder.readFromDatabase(JDBCBinder.java:88)
    at org.hibernate.cfg.JDBCMetaDataConfiguration.readFromJDBC(JDBCMetaDataConfiguration.java:42)
    at org.hibernate.tool.ant.JDBCConfigurationTask.doConfiguration(JDBCConfigurationTask.java:81)
    at org.hibernate.tool.ant.ConfigurationTask.getConfiguration(ConfigurationTask.java:55)
    at org.hibernate.tool.ant.HibernateToolTask.getConfiguration(HibernateToolTask.java:302)
    at org.hibernate.tool.ant.Hbm2DDLExporterTask.createExporter(Hbm2DDLExporterTask.java:51)
    at org.hibernate.tool.ant.ExporterTask.execute(ExporterTask.java:39)
    at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)
    ... 15 more
Caused by: java.sql.SQLException: No suitable driver found for jdbc:mysql:3306//localhost/db
    at java.sql.DriverManager.getConnection(DriverManager.java:602)
    at java.sql.DriverManager.getConnection(DriverManager.java:154)
    at org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:133)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getConnection(AbstractMetaDataDialect.java:122)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getMetaData(AbstractMetaDataDialect.java:61)
    ... 29 more
--- Nested Exception ---
org.hibernate.exception.JDBCConnectionException: Getting database metadata
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:97)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getMetaData(AbstractMetaDataDialect.java:64)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.caseForSearch(AbstractMetaDataDialect.java:163)
    at org.hibernate.cfg.reveng.dialect.JDBCMetaDataDialect.getTables(JDBCMetaDataDialect.java:22)
    at org.hibernate.cfg.reveng.JDBCReader.processTables(JDBCReader.java:476)
    at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:74)
    at org.hibernate.cfg.reveng.JDBCReader.readDatabaseSchema(JDBCReader.java:860)
    at org.hibernate.cfg.JDBCBinder.readDatabaseSchema(JDBCBinder.java:115)
    at org.hibernate.cfg.JDBCBinder.readFromDatabase(JDBCBinder.java:88)
    at org.hibernate.cfg.JDBCMetaDataConfiguration.readFromJDBC(JDBCMetaDataConfiguration.java:42)
    at org.hibernate.tool.ant.JDBCConfigurationTask.doConfiguration(JDBCConfigurationTask.java:81)
    at org.hibernate.tool.ant.ConfigurationTask.getConfiguration(ConfigurationTask.java:55)
    at org.hibernate.tool.ant.HibernateToolTask.getConfiguration(HibernateToolTask.java:302)
    at org.hibernate.tool.ant.Hbm2DDLExporterTask.createExporter(Hbm2DDLExporterTask.java:51)
    at org.hibernate.tool.ant.ExporterTask.execute(ExporterTask.java:39)
    at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:357)
    at org.apache.tools.ant.Target.performTasks(Target.java:385)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1298)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
    at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
    at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
Caused by: java.sql.SQLException: No suitable driver found for jdbc:mysql:3306//localhost/db
    at java.sql.DriverManager.getConnection(DriverManager.java:602)
    at java.sql.DriverManager.getConnection(DriverManager.java:154)
    at org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:133)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getConnection(AbstractMetaDataDialect.java:122)
    at org.hibernate.cfg.reveng.dialect.AbstractMetaDataDialect.getMetaData(AbstractMetaDataDialect.java:61)
    ... 29 more

J'utilise MySQL, et mes propriétés JDBC sont:

hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql:3306//localhost/db
hibernate.connection.username=root
hibernate.connection.password=root
hibernate.connection.show_sql=true

Mon pilote JDBC MySQL est en ${core.lib.server}: mysql-connector-java-5.1.7-bin.jar. (J'ai essayé aussi de mettre en classpath <fileset dir="/home/slorber/workspace/core/lib/server" includes="*.jar" />.)

J'ai également ajouté à la configuration de l'exécution classpath de Ant (plugin Eclipse).

Alors mes questions sont:

  • Ai-je fait quelque chose de mal à faire ce que je veux?
  • Est-ce la façon dont vous feriez une db migrer avec un framework Hibernate? (Et que feriez-vous faire d'autre sinon d'écrire toutes les modifications db dans les fichiers SQL faits à la main?)
Était-ce utile?

La solution

hbm2ddl une API n'ont que vous pouvez faire appel à votre propre. Si les tâches de fourmis existantes ne sont pas en train de faire ce que vous voulez, vous pouvez toujours faire le hbm2ddl vous appelle, peut-être même passer en veille prolongée un pilote jdbc surchargé qui enregistre exécuter des instructions plutôt que réellement les exécuter ou de surcharger l'hbm2ddl exécuter des méthodes.

Je voudrais aussi ajouter que vous devriez regarder à l'aide liquibase et la création de fichiers XML manuellement sur toute sorte de diffs. Vous reconnaissez que vous devrez valider le SQL généré est correct, il est tout aussi facile de créer une étape à la fois que vous développez, et alors vous savez qu'il est juste.

Nous utilisons en veille prolongée, et plutôt que d'utiliser l'liquibase mise en veille prolongée l'intégration, nous mettons à jour nos applications de mise en veille prolongée, exécutez nos tests d'intégration pour voir qu'ils ne parviennent pas, créez le changeset liquibase nécessaire (ajouter table, ajoutez la colonne, renommer colonne, etc.) , puis re-exécuter les tests et les voir passer. Construire l'étape de changelogs par étape fonctionne bien avec le rythme régulier du développement sans recourir à des diffs quoi que ce soit au-delà des contrôles de santé mentale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top