Grails 数据库迁移 gorm diff 没有产生任何变化

Grails database migration gorm diff yields no changes

背景

我有一个使用 3.0.14 的相对较新的 Grails 项目。我希望通过 Database Migration plugin (2.0.0.RC4).

为数据库迁移集成 liquibase

到目前为止,我有一个足够大的领域模型,我已经使用该插件来 'seed' 初始变更日志。这直接来自文档,并且按预期工作:

grails dbm-generate-gorm-changelog changelog.groovy

我现在正在尝试 test/get 工作的是 dbm-gorm-diff 命令,它将对域模型进行更改并创建可以应用的更改日志。这就是我 运行 遇到问题的地方。

Grails documentation 建议从数据源中删除 dbCreate 块以确保 Hibernate 不执行更新,而 Liquibase 可以接管。太好了,正是我想要的。

问题

当我删除 dbCreate 时,Grails/hibernate 似乎仍然在数据库迁移插件有机会执行差异之前更新数据库。在做 diff 时,已经来不及看到更改,因此更改日志不包含正确的数据。

配置

dataSource:
    pooled: true
    jmxExport: true
    driverClassName: org.h2.Driver
    username: sa
    password:

environments:
    development:
        dataSource:
            dbCreate: verify
            driverClassName: org.postgresql.Driver
            dialect: org.hibernate.dialect.PostgreSQLDialect
            url: jdbc:postgresql://127.0.0.1:5432/liquibase_test
            username: dbuser
            password: dbuser
            logSql: false
            formatSql: true

(我知道 dbCreate 设置为验证。稍后会详细介绍)

已采取的步骤

  1. 创建一个新的 postgres 数据库 - dbcreate -U dbuser liquibase_test
  2. 运行 新数据库的初始更新日志 - grails dbm-update
  3. 验证数据库现在是最新的,并检查 select * from databasechangelog 是否等于 changelog.groovy
  4. 中的更改数
  5. 添加一个新的简单域class:

    class TestDomain {
        int testInt
    }
    
  6. 运行 获取差异的插件 - grails dbm-gorm-diff add-simple-domain.groovy。命令失败并出现异常:

     :DataModel:dbmGormDiff
     Command execution error: liquibase.command.CommandExecutionException: java.lang.NullPointerException
     DataModel:dbmGormDiff FAILED
    
  7. 现在,删除上面的配置 dbCreate: verify,然后再次 运行

  8. 这一切都顺利完成,但有问题:

    • 命令创建了 add-simple-domain.groovy,但它没有提及我刚刚创建的新域 class。 (它有index/sequences,但我认为这是一个known issue
    • 新域 class 已添加 到数据库(!?)(已在 PgAdmin 中检查)
    • table databasechangelog 仍然有原始行数,甚至在询问时也没有引用新域 class

所以,我无法解释发生了什么。我可以处理额外的 create/drop 索引和序列,但我似乎无法让 liquibase 工作。谁能帮我解释一下这个问题?

编辑

我对 NullPointer 做了更多的挖掘,它似乎来自 class liquibase/ext/hibernate/snapshot/ForeignKeySnapshotGenerator.java:45,插件正在尝试为继承的 table 构造外键id 字段(使用 tablePerHierarchy false 进行继承)。经过适当的搜索后,我找不到任何似乎与此错误相关的内容。

编辑#2

我在 Github 上发现了 tablePerHierarchy NPE 的问题:https://github.com/grails-plugins/grails-database-migration/issues/68

更新数据源的 application.yml(或 application.groovy)配置:

dataSource:
    dbCreate: none

设置为 "none" 与完全删除 dbCreate 不同 - 您需要明确设置它以覆盖在别处设置的任何默认值。

"none" 在使用 JNDI 数据源时似乎对我不起作用并且仍然导致 ddl 运行。我将其设置为 "ignore" 以便能够在 Grails 3 中将 db-migrations 与 JNDI 数据源一起使用。0.x

我最终通过在我的 application.groovy 中设置 hibernate.hbm2ddl.auto = 'none' 来让它工作。有趣的是,当我尝试将相同的配置放入我的 application.yml 时,它没有任何效果。

我怀疑这里可能还有其他力量在起作用,因为我尝试在一个新的 Grails 项目上毫无问题地复制该行为。

目前我已经决定在 groovy 文件中使用休眠 属性,尽管我仍然很好奇为什么我无法让配置为我工作一个香草项目。