在不使用 hibernate.hbm2ddl.auto 的情况下,如何将所有初始模式导出到 Flyway?

Posted

技术标签:

【中文标题】在不使用 hibernate.hbm2ddl.auto 的情况下,如何将所有初始模式导出到 Flyway?【英文标题】:Without using hibernate.hbm2ddl.auto, how do I export all the initial schema into Flyway? 【发布时间】:2016-10-26 18:52:57 【问题描述】:

我的 JEE 开发几乎已准备就绪。很多人建议不要在生产中使用 Hibernate 的 hbm2ddl.auto,我决定将其删除。

所以现在,我发现了 Flyway,这对于未来的数据库更改和迁移来说似乎很棒,但我在第一步被卡住了:我有很多实体,一些实体继承自基础实体。这使得 CREATE 语句非常复杂。

创建第一个迁移文件的最佳做法是什么?

谢谢!

【问题讨论】:

您可能还会发现 Liquibase 很有帮助。我提到这一点并不是为了引发 Flyway 与 Liquibase 的争论,而是因为 Liquibase 将这个特殊的用例作为一流的概念来处理。具体见liquibase.org/documentation/generating_changelogs.html 【参考方案1】:

如果您在开发过程中采用“实体优先”的方法,则需要以与第一次实时部署相同的方式生成初始架构:这将生成 Flyway 使用的第一个创建脚本,并且可能还需要成为用于填充参考数据的第二个关联脚本。

简而言之,在第一次部署后不再能够使用hbm2ddl.auto 的原因是create 会破坏现有数据,而update 不够可靠,无法涵盖所有​​类型的架构更改(如听起来你可能已经从this SO question 知道了)。

Flyway 是一个非常有用的工具,但它确实需要一定程度的纪律,而这在开发过程中可能不存在。从初始版本开始,需要为 Flyway 生成数据库更新脚本,这些脚本等同于自上次发布以来对实体所做的更改。有一些工具(例如来自Redgate 的各种商业产品)可能会有所帮助:这些工具试图“区分”两个模式并生成模式和/或数据更新脚本,以便从数据库 A 到数据库 B。但根据我的经验,没有其中一些是完美的,但还没有完全达到启用完全自动化方法的圣杯。

可以说,最好的方法是“随用随用”的手动方法,以确保每当发生影响架构或引用数据的实体更改时,非破坏性更新脚本都会提交到源代码控制 - 但正如已经提到的,这将要求所有团队成员遵循一些纪律和/或记录的流程。

【讨论】:

感谢您的回答!! 1个问题:我正在使用JPA 2.1和postgresql,我使用PGAdmin导出了架构,并放置在src/main/resources/db/migration/V1__initial.sql中。接下来,使用'@Startup'和'@Singleton'创建一个类来初始化Flyway.migrate();迁移总是失败并显示超时消息。为什么? 使用命令行尝试migrate命令是否成功? 我找到了原因。这是因为编码问题。 .sql 文件必须采用 UTF8 格式,数据库引擎才能处理它。否则它会停留在那条线上。【参考方案2】:

对于第一个迁移文件,您只需要数据库的当前 ddl。有许多工具可以为您获取此信息(例如 IntelliJ IDEA 数据库工具中的“复制 ddl”选项或数据库供应商提供的 GUI 客户端)。

【讨论】:

【参考方案3】:

我不确定 Flyway,但有另一种方法,您可以使用 ant 任务进行休眠来生成或更新架构。

希望对你有帮助。

【讨论】:

【参考方案4】:

如果您使用 Maven 构建项目,则可以使用 Hibernate maven plugin。

【讨论】:

以上是关于在不使用 hibernate.hbm2ddl.auto 的情况下,如何将所有初始模式导出到 Flyway?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不安装 Zend 框架的情况下使用 Zend 库

在不使用存储过程的情况下循环 n 次

为啥 glDrawElments() 在不使用任何着色器的情况下工作?

在不使用地图Android的情况下获取用户(纬度,经度)位置[重复]

在不使用 ForEach 循环的情况下遍历列表

如何在不使用滤镜的情况下使图像变暗? [复制]