Liquibase Hibernate插件不起作用

如此处所述( https://github.com/liquibase/liquibase-hibernate/issues/74 )我遇到了使liquibase-hibernate扩展正常工作的问题。 我想我已经完成了所有设置,但似乎我一直遇到奇怪的问题。 我觉得我错过了一些简单的东西,但我想我已按照提供的所有说明进行操作。

我正在使用liquibase 3.3.2,Hibernate 4.3.0.Final,java 1.7.0_71和liquibase-hibernate4-3.5.jar。 我的CLASSPATH环境变量是空的,但liquibase shell脚本会添加一些东西。 当我使用正常的liquibase命令进行交互时,我从$ LIQUIBASE_HOME / lib /目录中删除了没有扩展名的扩展名,它可以正常工作。 我用DEBUG输出重新启动命令以提供更多信息。

$ echo $CLASSPATH $ java -version java version "1.7.0_71" Java(TM) SE Runtime Environment (build 1.7.0_71-b14) Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode) $ liquibase --version Liquibase Version: 3.3.2 $ liquibase diffChangeLog //The below is the stuff liquibase is adding to my classpath .:/c/repos/ServeDirtyLibsInJava/liquibaseLib/liquibase.jar:/c/repos/ServeDirtyLibsInJava/liquibaseLib/lib/liquibase-hibernate4-3.5.jar:/c/repos/ServeDirtyLibsInJava/liquibaseLib/lib/snakeyaml-1.13.jar WARNING 1/19/15 12:42 AM: liquibase: Can not use class liquibase.ext.hibernate.database.HibernateEjb3Database as a Liquibase service because org.hibernate.dialect.Dialect is not in the classpath WARNING 1/19/15 12:42 AM: liquibase: Can not use class liquibase.ext.hibernate.database.HibernateSpringDatabase as a Liquibase service because org.hibernate.dialect.Dialect is not in the classpath WARNING 1/19/15 12:42 AM: liquibase: Can not use class liquibase.ext.hibernate.database.HibernateClassicDatabase as a Liquibase service because org.hibernate.dialect.Dialect is not in the classpath DEBUG 1/19/15 10:20 AM: liquibase: Connected to root@localhost@jdbc:mysql://localhost:3306/dirtylibs DEBUG 1/19/15 10:20 AM: liquibase: Setting auto commit to false from true Unexpected error running Liquibase: java.lang.RuntimeException: Cannot find database driver: Driver class was not specified and could not be determined from the url (hibernate:spring:com.companyname.dirtylibs.persistence.entities?dialect=org.hibernate.dialect.MySQL5Dialect) SEVERE 1/19/15 10:20 AM: liquibase: java.lang.RuntimeException: Cannot find database driver: Driver class was not specified and could not be determined from the url (hibernate:spring:com.companyname.dirtylibs.persistence.entities?dialect=org.hibernate.dialect.MySQL5Dialect) liquibase.exception.DatabaseException: liquibase.exception.DatabaseException: java.lang.RuntimeException: Cannot find database driver: Driver class was not specified and could not be determined from the url (hibernate:spring:com.companyname.dirtylibs.persistence.entities?dialect=org.hibernate.dialec t.MySQL5Dialect) at liquibase.integration.commandline.CommandLineUtils.createDatabaseObject(CommandLineUtils.java:69) at liquibase.integration.commandline.Main.createReferenceDatabaseFromCommandParams(Main.java:1169) at liquibase.integration.commandline.Main.doMigration(Main.java:936) at liquibase.integration.commandline.Main.run(Main.java:175) at liquibase.integration.commandline.Main.main(Main.java:94) Caused by: liquibase.exception.DatabaseException: java.lang.RuntimeException: Cannot find database driver: Driver class was not specified and could not be determined from the url (hibernate:spring:com.companyname.dirtylibs.persistence.entities?dialect=org.hibernate.dialect.MySQL5Dialect) at liquibase.database.DatabaseFactory.openConnection(DatabaseFactory.java:239) at liquibase.database.DatabaseFactory.openDatabase(DatabaseFactory.java:143) at liquibase.integration.commandline.CommandLineUtils.createDatabaseObject(CommandLineUtils.java:50) ... 4 more Caused by: java.lang.RuntimeException: Cannot find database driver: Driver class was not specified and could not be determined from the url (hibernate:spring:com.companyname.dirtylibs.persistence.entities?dialect=org.hibernate.dialect.MySQL5Dialect) at liquibase.database.DatabaseFactory.openConnection(DatabaseFactory.java:191) ... 6 more 

我的liquibase.properties文件

 driver=com.mysql.jdbc.Driver classpath=mysql-connector-java-5.1.6.jar url=jdbc:mysql://localhost:3306/dirtylibs username=root password=password changeLogFile=changelog.xml #referenceDriver=liquibase.ext.hibernate.database.connection.HibernateDriver referenceUrl=hibernate:spring:com.companyname.dirtylibs.persistence.entities?dialect=org.hibernate.dialect.MySQL5Dialect referenceUsername=root referencePassword=password 

如果我取消注释我的referenceDriver,我会得到这个。 这里有什么我想念的吗? 我以为我有所有必需的依赖项,而且我不确定这是否是早期问题的一些表现,其中扩展无法正确加载内容。

 $ liquibase diffChangeLog WARNING 1/19/15 12:49 AM: liquibase: Can not use class liquibase.ext.hibernate.database.HibernateEjb3Database as a Liquibase service because org.hibernate.dialect.Dialect is not in the classpath WARNING 1/19/15 12:49 AM: liquibase: Can not use class liquibase.ext.hibernate.database.HibernateSpringDatabase as a Liquibase service because org.hibernate.dialect.Dialect is not in the classpath WARNING 1/19/15 12:49 AM: liquibase: Can not use class liquibase.ext.hibernate.database.HibernateClassicDatabase as a Liquibase service because org.hibernate.dialect.Dialect is not in the classpath WARNING 1/19/15 12:49 AM: liquibase: Can not use class liquibase.ext.hibernate.snapshot.SequenceSnapshotGenerator as a Liquibase service because org.hibernate.id.factory.IdentifierGeneratorFactory is not in the classpath WARNING 1/19/15 12:49 AM: liquibase: Can not use class liquibase.ext.hibernate.snapshot.TableSnapshotGenerator as a Liquibase service because org.hibernate.id.factory.IdentifierGeneratorFactory is not in the classpath Unexpected error running Liquibase: org.hibernate.sql.Alias SEVERE 1/19/15 10:22 AM: liquibase: org.hibernate.sql.Alias java.lang.NoClassDefFoundError: org/hibernate/sql/Alias at liquibase.ext.hibernate.snapshot.PrimaryKeySnapshotGenerator.(PrimaryKeySnapshotGenerator.java:27) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:526) at liquibase.snapshot.SnapshotGeneratorFactory.(SnapshotGeneratorFactory.java:29) at liquibase.snapshot.SnapshotGeneratorFactory.getInstance(SnapshotGeneratorFactory.java:43) at liquibase.snapshot.SnapshotControl.addType(SnapshotControl.java:95) at liquibase.snapshot.SnapshotControl.setTypes(SnapshotControl.java:88) at liquibase.snapshot.SnapshotControl.(SnapshotControl.java:25) at liquibase.command.DiffCommand.createReferenceSnapshot(DiffCommand.java:185) at liquibase.command.DiffCommand.createDiffResult(DiffCommand.java:140) at liquibase.command.DiffToChangeLogCommand.run(DiffToChangeLogCommand.java:51) at liquibase.command.AbstractCommand.execute(AbstractCommand.java:8) at liquibase.integration.commandline.CommandLineUtils.doDiffToChangeLog(CommandLineUtils.java:121) at liquibase.integration.commandline.Main.doMigration(Main.java:936) at liquibase.integration.commandline.Main.run(Main.java:175) at liquibase.integration.commandline.Main.main(Main.java:94) Caused by: java.lang.ClassNotFoundException: org.hibernate.sql.Alias at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 18 more 

将hibernate jar添加到liquibase / lib文件夹后(这确实是错误的),错误变成了这个。 我尝试恢复到旧版本的插件(同时降级liquibase),但它没有帮助。

 $ liquibase --logLevel=DEBUG diffChangeLog .:/c/repos/ServeDirtyLibsInJava/liquibaseLib/liquibase.jar:/c/repos/ServeDirtyLibsInJava/liquibaseLib/lib/hibernate-core-4.3.0.Final.jar:/c/repos/ServeDirtyLibsInJava/liquibaseLib/lib/liquibase-hibernate4-3.5.jar:/c/repos/ServeDirtyLibsInJava/liquibaseLib/lib/snakeyaml-1.13.jar WARNING 1/19/15 10:38 AM: liquibase: Can not use class liquibase.ext.hibernate.database.HibernateSpringDatabase as a Liquibase service because org.springframework.beans.factory.support.BeanDefinitionRegistry is not in the classpath DEBUG 1/19/15 10:38 AM: liquibase: Connected to root@localhost@jdbc:mysql://localhost:3306/dirtylibs DEBUG 1/19/15 10:38 AM: liquibase: Setting auto commit to false from true WARNING 1/19/15 10:38 AM: liquibase: Unknown database: Hibernate DEBUG 1/19/15 10:38 AM: liquibase: Connected to null@hibernate:spring:com.companyname.dirtylibs.persistence.entities?dialect=org.hibernate.dialect.MySQL5Dialect DEBUG 1/19/15 10:38 AM: liquibase: Not adjusting the auto commit mode; it is already false INFO 1/19/15 10:38 AM: liquibase: Error getting default schema java.lang.NullPointerException at liquibase.executor.jvm.JdbcExecutor$QueryCallableStatementCallback.doInCallableStatement(JdbcExecutor.java:383) at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:96) at liquibase.executor.jvm.JdbcExecutor.query(JdbcExecutor.java:132) at liquibase.executor.jvm.JdbcExecutor.query(JdbcExecutor.java:143) at liquibase.executor.jvm.JdbcExecutor.queryForObject(JdbcExecutor.java:151) at liquibase.executor.jvm.JdbcExecutor.queryForObject(JdbcExecutor.java:166) at liquibase.executor.jvm.JdbcExecutor.queryForObject(JdbcExecutor.java:161) at liquibase.database.AbstractJdbcDatabase.getConnectionSchemaName(AbstractJdbcDatabase.java:318) at liquibase.database.AbstractJdbcDatabase.getDefaultSchemaName(AbstractJdbcDatabase.java:301) at liquibase.CatalogAndSchema.customize(CatalogAndSchema.java:132) at liquibase.snapshot.SnapshotGeneratorFactory.createSnapshot(SnapshotGeneratorFactory.java:116) at liquibase.command.DiffCommand.createReferenceSnapshot(DiffCommand.java:190) at liquibase.command.DiffCommand.createDiffResult(DiffCommand.java:140) at liquibase.command.DiffToChangeLogCommand.run(DiffToChangeLogCommand.java:51) at liquibase.command.AbstractCommand.execute(AbstractCommand.java:8) at liquibase.integration.commandline.CommandLineUtils.doDiffToChangeLog(CommandLineUtils.java:121) at liquibase.integration.commandline.Main.doMigration(Main.java:936) at liquibase.integration.commandline.Main.run(Main.java:175) at liquibase.integration.commandline.Main.main(Main.java:94) DEBUG 1/19/15 10:38 AM: liquibase: Computed checksum for 1421681927678 as b60efdd1567f2fd4e5407a8d157cb0b6 Unexpected error running Liquibase: java.lang.NullPointerException SEVERE 1/19/15 10:38 AM: liquibase: java.lang.NullPointerException liquibase.exception.LiquibaseException: liquibase.command.CommandExecutionException: java.lang.NullPointerException at liquibase.integration.commandline.CommandLineUtils.doDiffToChangeLog(CommandLineUtils.java:123) at liquibase.integration.commandline.Main.doMigration(Main.java:936) at liquibase.integration.commandline.Main.run(Main.java:175) at liquibase.integration.commandline.Main.main(Main.java:94) Caused by: liquibase.command.CommandExecutionException: java.lang.NullPointerException at liquibase.command.AbstractCommand.execute(AbstractCommand.java:13) at liquibase.integration.commandline.CommandLineUtils.doDiffToChangeLog(CommandLineUtils.java:121) ... 3 more Caused by: java.lang.NullPointerException at liquibase.snapshot.jvm.CatalogSnapshotGenerator.getDatabaseCatalogNames(CatalogSnapshotGenerator.java:82) at liquibase.snapshot.jvm.CatalogSnapshotGenerator.snapshotObject(CatalogSnapshotGenerator.java:41) at liquibase.snapshot.jvm.JdbcSnapshotGenerator.snapshot(JdbcSnapshotGenerator.java:60) at liquibase.snapshot.SnapshotGeneratorChain.snapshot(SnapshotGeneratorChain.java:50) at liquibase.snapshot.DatabaseSnapshot.include(DatabaseSnapshot.java:163) at liquibase.snapshot.DatabaseSnapshot.init(DatabaseSnapshot.java:55) at liquibase.snapshot.DatabaseSnapshot.(DatabaseSnapshot.java:37) at liquibase.snapshot.JdbcDatabaseSnapshot.(JdbcDatabaseSnapshot.java:25) at liquibase.snapshot.SnapshotGeneratorFactory.createSnapshot(SnapshotGeneratorFactory.java:126) at liquibase.snapshot.SnapshotGeneratorFactory.createSnapshot(SnapshotGeneratorFactory.java:119) at liquibase.command.DiffCommand.createReferenceSnapshot(DiffCommand.java:190) at liquibase.command.DiffCommand.createDiffResult(DiffCommand.java:140) at liquibase.command.DiffToChangeLogCommand.run(DiffToChangeLogCommand.java:51) at liquibase.command.AbstractCommand.execute(AbstractCommand.java:8) ... 4 more 

我通过将这些jar子添加到我的类路径中来实现它。 这是非常令人困惑的,没有很好的记录。 我经历的过程是:

  1. 下载这里找到的正确插件项目的源代码( https://github.com/liquibase/liquibase-hibernate/releases )在我的情况下它是liquibase-hibernate4-3.5。

  2. 运行mvn dependency:copy-dependencies 。 这会将它们转储到/target/dependency/ 。 复制所有这些jar并将它们放入LIQUIBASE_HOME/lib目录中。

  3. 我正在使用gradle,所以我使用自定义任务来复制所有依赖项。 如果你正在使用maven,你可以使用自己项目中2的相同步骤来获取所有的depdenencies。 我将这些库从输出目录复制到LIQUIBASE_HOME/lib目录中。

     task copyToLib(type: Copy) { into "$buildDir/output/libs" from configurations.runtime } 
  4. 我还将正确的hibernate-liquibase-4.3.5.jar放入LIQUIBASE_HOME/lib目录中。

这给了我插件所需的所有依赖项。

这是一个令人讨厌的混乱球,但你能做什么:(

如果检查此插件的源代码,则以下依赖项(所有spring依赖项)在pom中标记为“提供”范围:

 spring-test spring-jdbc spring-beans spring-context spring-orm 

因此,插件将假设这些已经由您的应用程序在类路径上提供,但这不会自动发生在您的maven构建中,因为它不会运行与您的应用程序相同的类路径。

所以,要修复,在插件中添加依赖项,比执行jar文件shuffle更容易:

  org.liquibase liquibase-maven-plugin 3.4.1   org.liquibase.ext liquibase-hibernate5 3.6   org.liquibase liquibase-core 3.5.3   org.springframework spring-jdbc 4.3.2.RELEASE   org.springframework spring-beans 4.3.2.RELEASE   org.springframework spring-context 4.3.2.RELEASE   org.springframework spring-orm 4.3.2.RELEASE    

如果你很热衷,可以在github repo上做一个pull请求,从pom中删除提供的范围,哦,也可能是这行:

  architect 

我尝试的路径与接受的anwer有点不同。 我在war的pom.xml中创建了一个dev配置文件(我正在使用maven),它与默认配置文件完全相同,但包含war / WEB-INF / lib下的Liquibase-hibernate依赖jar文件。 然后不使用提供的liquibase命令行,而是直接使用liquibase.jar文件,类路径是我的war文件:

 java -jar $LIQUIBASE/liquibase.jar --classpath= --defaultsFile=/liquibase.properties --logLevel=info 

然后创建一个connvenience脚本,它将使用liquibase-hibernate配置文件构建我的项目,然后执行diffChangeLog命令。

我得到了同样的错误。 我通过删除hibernate.cfg.xml中的hbm2ddl-property来修复它。 如果启用此属性,则无法在cfg.xml中读取驱动程序类。 liit中的liquibase-hibernate wiki中有一部分显示“为什么不使用HBM2DDL”,但它并没有真正说明要从cfg.xml中删除它。