从Hibernate 4迁移到5 [英] Migration from Hibernate 4 to 5

查看:198
本文介绍了从Hibernate 4迁移到5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试迁移到使用Hibernate 5的Spring Boot 1.4。
我有一个包含表创建的MariaDB数据库的备份脚本。



到期在Spring Boot中,我的实体使用了以下id生成策略。

  @GeneratedValue(strategy = GenerationType。 AUTO)

在我的 application.properties I有

  spring.jpa.generate-ddl = true 
spring.jpa.hibernate.use-new-id- generator-mappings = false

Hibernate团队通常不会推荐此设置(false值)。



如果我让hibernate生成表,看起来与备份脚本中的有些不同。



如果我使用关于生成器的虚假值并使用备份脚本并在此之后设置为true,我会得到一些有关外键的问题。


无法添加或更新子行:外键构造aint fail ...

如果我保持为false,我会得到相同的结果。



我可以使用什么策略迁移到Hibernate 5的新生成器,并拥有旧数据库的数据(而不是结构)?

有什么方法可以停留更通用?不是特定于Hibernate的

解决方案

你面对的问题是,在Hibernate 4和之前的版本中,使用 GenerationType。 AUTO 表示如果您连接的数据库支持 IDENTITY AUTO_INCREMENT 数据类型,那些比使用基于表格的序列更受欢迎。

使用Hibernate 5, GenerationType.AUTO 将默认使用以前用于数据库的基于表的序列 IDENTITY AUTO_INCREMENT 。逻辑变化的原因有点复杂,但足以说有更好的选择。



我的建议将是一个多步迁移路径,因为这将是根据表格的大小和数量以及您的实体之间的关系,这是很乏味的。


  1. 首先,不要使用新的标识符映射生成器(例如使用 false )。

  2. 确认一切正常,即是现状。所有 @GeneratedValue 注释使用 GenerationType.IDENTITY

  3. 更改为使用标识符映射生成器(例如,使用 true )。 ,即现状。

此时,您不必更改数据库中的任何内容,来自备份。你所做的全部都是Java代码的移植,这样对于新实体,你可以使用新的标识符映射,并保留现有实体的旧方式。



从这一点转发,我建议一次迁移一个实体。


  1. 更改java类以使用由 hibernate_sequences 表支持的命名序列生成器。
  2. 确定实体数据的 MAX(ID),并在 hibernate_sequences 表中指定该实体的命名标识符。

  3. 这里单调乏味的部分是您需要删除与此实体现有的 ID 列相关的所有外键,改变它的数据类型,使它不是 AUTO_INCREMENT IDENTITY ,而是最可能的是像 BIGINT INT 。然后你想把外键约束放回去。

此时,该实体应该开始使用序列表的逻辑而不是在Hibernate之前使用的本地 AUTO_INCREMENT IDENTITY 功能 AUTO 5,对于大型复杂的系统,这不会很有趣。

我必须评估我们是否适应了过去项目中ORM5中的新标识符,并确定了适应复杂的现有模式所涉及的时间不值得它。我们最终完成了前1-5步,保持现状,然后允许新实体利用新的东西。这个计划是让开发人员随着时间的推移返回并根据需要完成最后1-3步。


I try to migrate to Spring Boot 1.4 that uses Hibernate 5. I have some backup script of a MariaDB database that includes table creation.

Due to spring-data-jpa in Spring Boot my entities are using the following id generation strategy.

@GeneratedValue(strategy = GenerationType.AUTO)

In my application.properties I have

spring.jpa.generate-ddl=true
spring.jpa.hibernate.use-new-id-generator-mappings=false

The Hibernate team generally don’t recommend this setting (false value).

If I let hibernate generate the table, seem some differences with the one in the backup script.

If I use false value about the generator and use the backup script and set after that to true, I get some issue about oreign key

Cannot add or update a child row: a foreign key constraint fail...

I get same result if I keep to false.

What strategy can I use to migrate to new generator of Hibernate 5 and have data of my old database (not the structure)?

Is there a way to stay more generic? not specific to Hibernate

解决方案

The issue you face is that in Hibernate 4 and prior, using GenerationType.AUTO implied that if the database you're connected to supported IDENTITY or AUTO_INCREMENT data types, those would be preferred over using table-based sequences.

With Hibernate 5, GenerationType.AUTO will default to using table-based sequences for databases that previously would have used IDENTITY or AUTO_INCREMENT. The reason for the logic change is a bit complex, but suffice to say there are better alternatives.

My suggestion would be a multi-step migration path because this is going to be tedious depending on the size and number of tables and relationships between your entities.

  1. First, don't use the new identifier mapping generators (e.g. use false).
  2. Verify everything works, aka status-quo.
  3. Change all your @GeneratedValue annotations to use GenerationType.IDENTITY.
  4. Change to use identifier mapping generators (e.g. use true).
  5. Verify everything works, aka status-quo.

At this point, you haven't had to change anything in your database, its stayed preciously as it was from the backup. All you've done is migrated the java code so that for new entities, you can use the new identifier mappings and preserve the old way for existing entities.

From this point forward, I would suggest migrating one entity at a time.

  1. Change the java class to use a named sequence generator backed by the hibernate_sequences table.
  2. Determine the MAX(ID) of your entity's data and set the appropriate next id value in the hibernate_sequences table for that entity's named identifier.
  3. The tedious part here is you'll need to drop all your foreign keys related to this entity's existing ID column, alter its data type so that it isn't AUTO_INCREMENT or IDENTITY but instead most likely something like BIGINT or INT. Then you want to put the foreign key constraints back.

At this point, that entity should begin using the sequence table's logic rather than the native AUTO_INCREMENT or IDENTITY functionality that AUTO used prior to Hibernate 5.

For large, complex systems, this won't be fun.

I had to evaluate whether we adapted to the new identifier things in ORM5 for a past project and we determined the time involved to adapt a complex, existing schema wasn't worth it. We ended up doing the first 1-5 steps to remain status-quo and then allowed new entities to leverage the new stuff. The plan was for developers go back and finish the last 1-3 steps on an as-needed basis over time.

这篇关于从Hibernate 4迁移到5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆