从 Hibernate 4 迁移到 5
Migration from Hibernate 4 to 5
我尝试迁移到 Spring 使用 Hibernate 5 的 Boot 1.4。
我有一些 MariaDB 数据库的备份脚本,其中包括 table 创建。
由于 spring-data-jpa 在 Spring 引导中,我的实体正在使用以下 ID 生成策略。
@GeneratedValue(strategy = GenerationType.AUTO)
在我的 application.properties
我有
spring.jpa.generate-ddl=true
spring.jpa.hibernate.use-new-id-generator-mappings=false
Hibernate 团队通常不推荐此设置(假值)。
如果我让休眠生成table,似乎与备份脚本中的有些不同。
如果我对生成器使用假值并使用备份脚本并将其设置为真,我会遇到一些关于外键的问题
Cannot add or update a child row: a foreign key constraint fail...
如果我保持为 false,我会得到相同的结果。
我可以使用什么策略迁移到 Hibernate 5 的新生成器并拥有旧数据库的数据(不是结构)?
有没有办法保持更通用?不特定于 Hibernate
您面临的问题是,在 Hibernate 4 和之前的版本中,使用 GenerationType.AUTO
意味着如果您连接的数据库支持 IDENTITY
或 AUTO_INCREMENT
数据类型,那么这些数据类型将优于使用基于 table 的序列。
在 Hibernate 5 中,GenerationType.AUTO
将默认为以前使用 IDENTITY
或 AUTO_INCREMENT
的数据库使用基于 table 的序列。逻辑变化的原因有点复杂,但足以说明有更好的选择。
我的建议是采用多步迁移路径,因为根据 table 的大小和数量以及您的实体之间的关系,这会很乏味。
- 首先,不要使用新的标识符映射生成器(例如使用
false
)。
- 验证一切正常,也就是保持现状。
- 将所有
@GeneratedValue
注释更改为使用 GenerationType.IDENTITY
。
- 改为使用标识符映射生成器(例如使用
true
)。
- 验证一切正常,也就是保持现状。
此时,您还没有更改数据库中的任何内容,它与备份中的一样珍贵。您所做的只是迁移了 java 代码,以便对于新实体,您可以使用新的标识符映射并为现有实体保留旧方法。
从现在开始,我建议一次迁移一个实体。
- 更改 java class 以使用由
hibernate_sequences
table. 支持的命名序列生成器
- 确定实体数据的 MAX(ID) 并在
hibernate_sequences
table 中为该实体的命名标识符设置适当的下一个 id 值。
- 这里繁琐的部分是您需要删除与该实体现有 ID 列相关的所有外键,更改其数据类型,使其不是
AUTO_INCREMENT
或 IDENTITY
但很可能是 BIGINT
或 INT
。然后你想把外键约束放回去。
此时,该实体应该开始使用序列 table 的逻辑,而不是 AUTO
在 Hibernate 之前使用的本机 AUTO_INCREMENT
或 IDENTITY
功能5.
对于大型、复杂的系统,这不会很有趣。
我必须评估我们是否为过去的项目适应了 ORM5 中的新标识符,我们确定适应复杂的现有模式所花费的时间是不值得的。我们最终执行了前 1-5 个步骤以保持现状,然后允许新实体利用新东西。该计划是让开发人员返回并随着时间的推移根据需要完成最后 1-3 个步骤。
我尝试迁移到 Spring 使用 Hibernate 5 的 Boot 1.4。 我有一些 MariaDB 数据库的备份脚本,其中包括 table 创建。
由于 spring-data-jpa 在 Spring 引导中,我的实体正在使用以下 ID 生成策略。
@GeneratedValue(strategy = GenerationType.AUTO)
在我的 application.properties
我有
spring.jpa.generate-ddl=true
spring.jpa.hibernate.use-new-id-generator-mappings=false
Hibernate 团队通常不推荐此设置(假值)。
如果我让休眠生成table,似乎与备份脚本中的有些不同。
如果我对生成器使用假值并使用备份脚本并将其设置为真,我会遇到一些关于外键的问题
Cannot add or update a child row: a foreign key constraint fail...
如果我保持为 false,我会得到相同的结果。
我可以使用什么策略迁移到 Hibernate 5 的新生成器并拥有旧数据库的数据(不是结构)?
有没有办法保持更通用?不特定于 Hibernate
您面临的问题是,在 Hibernate 4 和之前的版本中,使用 GenerationType.AUTO
意味着如果您连接的数据库支持 IDENTITY
或 AUTO_INCREMENT
数据类型,那么这些数据类型将优于使用基于 table 的序列。
在 Hibernate 5 中,GenerationType.AUTO
将默认为以前使用 IDENTITY
或 AUTO_INCREMENT
的数据库使用基于 table 的序列。逻辑变化的原因有点复杂,但足以说明有更好的选择。
我的建议是采用多步迁移路径,因为根据 table 的大小和数量以及您的实体之间的关系,这会很乏味。
- 首先,不要使用新的标识符映射生成器(例如使用
false
)。 - 验证一切正常,也就是保持现状。
- 将所有
@GeneratedValue
注释更改为使用GenerationType.IDENTITY
。 - 改为使用标识符映射生成器(例如使用
true
)。 - 验证一切正常,也就是保持现状。
此时,您还没有更改数据库中的任何内容,它与备份中的一样珍贵。您所做的只是迁移了 java 代码,以便对于新实体,您可以使用新的标识符映射并为现有实体保留旧方法。
从现在开始,我建议一次迁移一个实体。
- 更改 java class 以使用由
hibernate_sequences
table. 支持的命名序列生成器
- 确定实体数据的 MAX(ID) 并在
hibernate_sequences
table 中为该实体的命名标识符设置适当的下一个 id 值。 - 这里繁琐的部分是您需要删除与该实体现有 ID 列相关的所有外键,更改其数据类型,使其不是
AUTO_INCREMENT
或IDENTITY
但很可能是BIGINT
或INT
。然后你想把外键约束放回去。
此时,该实体应该开始使用序列 table 的逻辑,而不是 AUTO
在 Hibernate 之前使用的本机 AUTO_INCREMENT
或 IDENTITY
功能5.
对于大型、复杂的系统,这不会很有趣。
我必须评估我们是否为过去的项目适应了 ORM5 中的新标识符,我们确定适应复杂的现有模式所花费的时间是不值得的。我们最终执行了前 1-5 个步骤以保持现状,然后允许新实体利用新东西。该计划是让开发人员返回并随着时间的推移根据需要完成最后 1-3 个步骤。