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 设置为验证。稍后会详细介绍)
已采取的步骤
- 创建一个新的 postgres 数据库 -
dbcreate -U dbuser liquibase_test
- 运行 新数据库的初始更新日志 -
grails dbm-update
- 验证数据库现在是最新的,并检查
select * from databasechangelog
是否等于 changelog.groovy
中的更改数
添加一个新的简单域class:
class TestDomain {
int testInt
}
运行 获取差异的插件 - grails dbm-gorm-diff add-simple-domain.groovy
。命令失败并出现异常:
:DataModel:dbmGormDiff
Command execution error: liquibase.command.CommandExecutionException: java.lang.NullPointerException
DataModel:dbmGormDiff FAILED
现在,删除上面的配置 dbCreate: verify
,然后再次 运行
这一切都顺利完成,但有问题:
- 命令创建了
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 文件中使用休眠 属性,尽管我仍然很好奇为什么我无法让配置为我工作一个香草项目。
背景
我有一个使用 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 设置为验证。稍后会详细介绍)
已采取的步骤
- 创建一个新的 postgres 数据库 -
dbcreate -U dbuser liquibase_test
- 运行 新数据库的初始更新日志 -
grails dbm-update
- 验证数据库现在是最新的,并检查
select * from databasechangelog
是否等于changelog.groovy
中的更改数
添加一个新的简单域class:
class TestDomain { int testInt }
运行 获取差异的插件 -
grails dbm-gorm-diff add-simple-domain.groovy
。命令失败并出现异常::DataModel:dbmGormDiff Command execution error: liquibase.command.CommandExecutionException: java.lang.NullPointerException DataModel:dbmGormDiff FAILED
现在,删除上面的配置
dbCreate: verify
,然后再次 运行这一切都顺利完成,但有问题:
- 命令创建了
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 文件中使用休眠 属性,尽管我仍然很好奇为什么我无法让配置为我工作一个香草项目。