Domanda

Io uso:

  • EJB3 / JPA (Hibernate)
  • MySQL 5

Devo impostare un sistema per aiutare le migrazioni di database. Ho cercato di usare LiquiBase ma non sembra abbastanza maturo ancora per essere utilizzato con Hibernate.

Quello che vorrei fare è:

  • Ho la versione 1.0 dell'applicazione della produzione
  • Ho la versione 2.0 dell'applicazione sviluppato e testato
  • Se si desidera aggiornare il database dell'applicazione in produzione senza perdere i dati

In realtà vorrei utilizzare il nuovo persistence.xml e il database di produzione per essere in grado di generare il "delta" tra il vecchio database e il nuovo. Mi piacerebbe essere in grado di recuperare il codice SQL che viene eseguito quando hbm2ddl è in modalità "update".

Questo codice SQL sarà modificata (goccia + creare = rinomina, ecc ...) per evitare di perdere i dati che potrebbero accadere con hbm2ddl.auto=update.

Credo che sia possibile perché Hibernate fa durante la distribuzione di una nuova versione con hbm2ddl.auto=update. Ma io voglio essere in grado di farlo in un compito Ant con hibernatetool.

Non trovo molte informazioni su questo su internet quindi mi chiedo se qualcuno ha già fatto qualcosa di simile qui e mi potrebbe aiutare.

Ho fatto il seguente:

<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>

Io in realtà non so come fare, sono stato in grado di ottenere il file sql creazione, ma voglio solo il delta. Devo mettere aggiornamento = "true"? Posso utilizzare l'jpaconfig con l'unità di persistenza al di fuori del server di applicazione (le impostazioni di db sono impostate su JNDI ressource su Glassfish). (Provato e semplicemente non riesce a trovare il db)

Ho provato anche con <jdbcconfiguration propertyfile="hibtest.properties"></jdbcconfiguration> o impostazione delle proprietà del database in persistence.xml invece di utilizzare risorse JNDI.

ho ottenuto il seguente errore:

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

Io uso di MySQL, e le mie proprietà JDBC sono:

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

Il mio driver JDBC MySQL è in ${core.lib.server}: mysql-connector-java-5.1.7-bin.jar. (Ho anche provato a mettere in <fileset dir="/home/slorber/workspace/core/lib/server" includes="*.jar" /> classpath.)

Ho anche aggiunto al classpath configurazione di esecuzione di Ant (Plug-in Eclipse).

Quindi le mie domande sono le seguenti:

  • Ho fatto qualcosa di sbagliato a fare quello che voglio?
  • E 'questo il modo in cui si farebbe un db migrano con un quadro Hibernate? (E che altro faresti se non scrivere tutti i cambiamenti db nei file SQL fatti a mano?)
È stato utile?

Soluzione

Hbm2ddl ha un'API è possibile chiamare da soli. Se i compiti formica esistenti non stanno facendo ciò che si vuole, si può sempre fare la hbm2ddl chiama te stesso, forse anche passando ibernare un driver JDBC overload che registra eseguire istruzioni, piuttosto che effettivamente l'esecuzione o di sovraccaricare il hbm2ddl eseguire metodi.

Vorrei anche aggiungere che si dovrebbe guardare con liquibase e la creazione di file XML manualmente su ogni tipo di diff. Si riconosce che è necessario verificare che il codice SQL generato è corretta, è altrettanto facile creare un passo alla volta, come si sviluppa, e allora sai che è giusto.

Usiamo Hibernate, e piuttosto che utilizzare il liquibase ibernazione integrazione, che aggiorniamo il nostro mapping Hibernate, eseguire i nostri test di integrazione per vedere che essi non riescono, creare la necessaria changeset liquibase (aggiungere tavolo, aggiungere colonne, rinominare colonna, ecc) , poi ri-eseguire i test e vedere passare. Costruire passo dopo passo i changelog funziona bene con il ritmo regolare di sviluppo senza ricorrere a diff per qualsiasi cosa al di là di controlli di integrità.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top