首页 > 解决方案 > 如何在不需要迁移插件的情况下使用 Grails 4.0.5 (Hibernate 5) 在模式生成期间添加自定义数据库对象?

问题描述

我需要添加一些作为系统架构设计一部分的函数和视图。这应该是会话启动的一部分(尤其是在开发和测试中),因为数据源上的 dbCreate create-drop 设置使得初始开发和测试环境最初设置一致且原始。

使用数据库迁移插件没有意义,因为这些是预定义的 db 对象,它们是整个系统设计的一部分,除非它们本身正在更改,否则它们不属于更改集。相当于要求我们在变更集中添加域表生成sql。如果它正在发生变化(这就是变更集的用途!),这是有道理的,但如果它只是最初创建的,那么它在概念上放置它的位置是错误的。

此外,我们不能使用迁移插件,因为我们的生产 QA 流程不允许这种方法(它是与项目源无关的外部流程,因此在多个项目中维护更改集没有意义)。

Hibernate 从 grails 域对象自动生成它的模式,我们有视图的 sql(依赖于域对象中的表)以及这些视图中使用的一些函数的 sql,我们只需要确定在哪里最好让 GORM / Hibernate 执行所述 sql,以便在生成模式时生成适当的 db 对象。

在 Grails 2.5.5 中,我使用自定义 GrailsAnnotationConfiguration 来挂钩模式生成过程。这不再是在 grails 4+ 中使用 Hibernate 5 的选项。

为了在不依赖数据库迁移插件的情况下添加自定义数据库对象(如函数和视图),与 Hibernate Schema 生成过程相关联的最佳方法是什么?

标签: hibernategrailsgrails-4hibernate-5

解决方案


目前(Grails 4.05)答案似乎是使用数据库迁移插件(如原始问题中所述,这对我来说不合适)或使用自定义 HibernateMappingContextConfiguration 以便通过覆盖将您自己的休眠“AuxiliaryDatabaseObject”注入会话工厂buildSessionFactory() 方法。这些对象记录在 Hibernate 文档中,配置在 GORM 文档中提到。

为辅助数据库对象指定映射的所有尝试均失败。我无法让 Gorm / Grails 关注休眠配置和映射文件。目前尚不清楚,或者这是故意的还是错误的。无论如何,我需要一种不同的方法。

幸运的是,HibernateMappingContextConfiguration 支持直接添加 AuxiliaryDatabaseObject,通过它您可以有效地注入创建或删除辅助 db 对象(包括函数、视图甚至任意 sql)所需的任何 SQL。

这对我有用,并且具有以这种方式注入的任何代码(自然地)传递到使用模式导出时生成的 ddl 的优点,当数据库管理(包括更改集管理)是外部的时,这是必要的,使用导出的 ddl 是生成的工件。

此外,这使您可以使用“create-drop”作为数据源来保持您的开发环境(因此它始终从原始模式启动)。

例如:

MyHibernateMappingContextConfiguration extends HibernateMappingContextConfiguration {
  @Override
  SessionFactory buildSessionFactory() throws HibernateException {
    //...
    //create and add AuxiliaryDatabaseObject instances as needed
    super.addAuxiliaryDatabaseObject(myAuxiliaryDatabaseObject)
    //...
    return super.buildSessionFactory() 
  }
}

然后只需通过 application.yml 配置 hibernate 以使用您的自定义上下文配置:

hibernate:
    configClass: path.to.MyHibernateMappingContextConfiguration  

推荐阅读