2009-07-17 67 views
2

我用:Db的迁移 - 休眠/ JPA - 就是hbm2ddl - 差异工具

  • EJB3/JPA(休眠)
  • MySQL的5

我必须建立一个系统,以帮助数据库迁移。试过使用LiquiBase,但它似乎还不够成熟,但与Hibernate一起使用。

我想什么做的是:

  • 我有1.0版应用程序在生产
  • 我开发的应用程序的2.0版本和测试
  • 我想更新应用程序数据库在生产过程中没有丢失数据

其实我想用新的persistence.xml和生产数据库能够生成“三角洲”之间旧数据库和新数据库。我希望能够检索hbm2ddl处于“更新”模式时执行的SQL代码。

此SQL代码将被修改(drop + create = rename等...),以避免丢失可能与hbm2ddl.auto=update发生的数据。

我想这是可能的,因为Hibernate在部署hbm2ddl.auto=update的新版本时会这样做。但我希望能够在与hibernatetool的Ant任务中执行此操作。

我没有在互联网上找到关于此的许多信息,所以我想知道是否有人已经在这里做了类似的事情,可以帮助我。

我已经做了以下内容:

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

我真的不知道该怎么办,我是能够得到创建SQL文件,但我只是想三角洲。 我必须把更新=“真”? 我可以在应用程序服务器之外使用持久性单元的jpaconfig(db设置在Glassfish上的JNDI资源上设置)。 (试过,它只是找不到数据库)

我也尝试<jdbcconfiguration propertyfile="hibtest.properties"></jdbcconfiguration>或设置persistence.xml数据库的属性,而不是使用JNDI资源。

我得到了以下错误:

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 

我使用MySQL和我的JDBC属性是:

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 

我的JDBC MySQL驱动是${core.lib.server}: mysql-connector-java-5.1.7-bin.jar。 (我也尝试把类路径<fileset dir="/home/slorber/workspace/core/lib/server" includes="*.jar" />。)

我也将它添加到Ant(Eclipse插件)的运行配置类路径。

所以我的问题是:

  • 难道我做错了什么事做我想要什么?
  • 这是你将使用Hibernate框架进行数据库迁移的方式吗? (如果不是在手工制作的SQL文件中编写所有数据库更改,您还会做什么?)
+0

有趣,我最阅读的线程之一,而不是任何+1:D – 2011-11-17 00:25:00

回答

2

Hbm2ddl确实有一个您可以自己调用的API。如果现有的ant任务没有达到你想要的,你总是可以自己进行hbm2ddl调用,甚至可以通过hibernate传递一个重载的jdbc驱动程序来记录执行语句,而不是实际执行它们或者重载hbm2ddl execute方法。

我也会补充一点,你应该看看使用liquibase和手动创建XML文件的任何差异。您意识到您需要验证生成的sql是否正确,在开发时一次只创建一个步骤就很容易,然后您知道它是正确的。

我们使用hibernate,而不是使用liquibase hibernate集成,我们更新了hibernate映射,运行我们的集成测试以查看它们失败,创建必要的liquibase变更集(添加表,添加列,重命名列等)。 ),然后重新运行测试并看到它们通过。逐步建立更新日志可以和正常的开发节奏一起工作,而不需要区分除了完整性检查之外的任何事情。