结合Hibernate的自动模式创建和数据库版本控制

9
我有一个应用程序,Hibernate会在机器上第一次运行时创建所有表结构,这很好。现在我想知道Hibernate是否有某种机制来控制数据库版本,即当我运行不同版本的应用程序时,Hibernate是否知道如何将一个模式迁移到另一个模式,如果Hibernate发现旧版本中存在不同的数据库模式?我认为这应该是可能的,因为Hibernate可以读取现有的模式,并且可以将模式与映射描述进行比较。但我不知道如何告诉Hibernate迁移旧数据,就像使用Liquibase / Flyway创建更改脚本一样。我可能没有搜索到正确的内容,因为Hibernate和版本控制会显示很多关于审计和字段版本控制的结果,但我更多地考虑Liquibase / Flyway类型的版本控制。我从未考虑过两者之间的联系,但由于Hibernate不创建更新脚本而是直接操作数据库,我不知道如何使两者配合工作。
这是我第一次让Hibernate创建我的模式,而不是编写自己的脚本。我这样做是为了利用Hibernate Envers,这使得手动脚本创建变得更加繁琐。也许我错过了一些显而易见的东西。感谢任何关于此事的意见!
更新:今天我与Flyway的开发人员交谈,他告诉我他不知道有什么好的解决方案。也许没有什么?

Hibernate的hbm2ddl.auto值为“update”,它会尝试执行此操作,但不可靠。根据我的Hibernate经验,这些模式更新应始终由手动编写的模式更新SQL脚本处理。通常,应用程序使用的数据库用户也不应具有创建/删除权限,尽管这可能不适用于您的情况。 - Taylor
在我看来,最后的模式编写有点代码重复,因为它只是镜像实现了我的Java对象所描述的领域模型。通常,这种重复并不那么昂贵,但在Envers中却是如此。因此,我希望能够找到解决方案。您在什么情况下发现hbm2dll.auto不足以满足需求?这可能是实现自定义Flyway迁移器的一个很好的入口点。 - Rafael Winterhalter
几乎所有情况下,除了“添加具有单个默认值的列”或“删除此列”之外,任何对现有列进行重新组织或更改的操作都超出了Hibernate更新的能力。 - Taylor
1个回答

11
我们的Java/Hibernate项目也遇到了同样的问题,不希望有任何重复编码的工作。Hibernate 的“update”功能并不可靠,LiquidBase 更好一些,但也不是100%可靠的。最终,我们开发了一个简单的脚本来管理以下过程:
  1. 当前数据库模式始终由Hibernate直接针对DEV数据库生成。
  2. 通过一系列LiquiBase更改集生成“先前”的数据库模式。
  3. 每次需要迁移时,会在“先前”和“当前”数据库之间(确实更可靠)调用LiquiBase“diff”函数,生成一个新的LiquiBase更改集。
  4. 需要手动审核此更改集。所有更改集都保存在源代码控制中。
  5. 应用所有LiquiBase更改集后,生产数据库将生成其模式。
我们脚本中的关键命令如下所示:
${LIQB_COMMAND} ${PREV_DB_OPTIONS} --changeLogFile=${LIQB_CHGLOG_FILE_NEW}  \
    diffChangeLog \
                --referenceUsername=${DEV_DB_USER} \
                --referencePassword=${DEV_DB_PWD} \
                --referenceDriver=com.mysql.jdbc.Driver \
                --referenceUrl=${DEV_DB_URL}

这种方式使我们的迁移过程非常可靠,而且您不需要编写两次模式代码。生成的变更集会以 XML 的形式进行手动审核,但大多数情况下都没有问题,相比手动编写模式更容易。


是的。Liquibase是您想要使用的工具。Hibernate的自动DDL功能主要是用于开发/测试工具。我相信大多数好的Hibernate书籍都提到了这一点,所以我不确定为什么人们会尝试使用自动DDL来进行生产模式迁移。 - Joshua Davis
1
因为这很方便,我猜。但我认为我需要朝着这样的解决方案前进。你没有开源你的解决方案吗? - Rafael Winterhalter
你知道吗,我其实不介意这样做。只是这部分代码有点嵌入到我们的项目中了。要进一步清理它并使其对你和其他人有用需要花费一些努力。如果你确定想要这条路线,我可以帮忙清理代码,使其对其他人有用。 - stevel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接