从Hibernate 4迁移到5 [英] Migration from Hibernate 4 to 5
问题描述
我有一个包含表创建的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
。逻辑变化的原因有点复杂,但足以说有更好的选择。
我的建议将是一个多步迁移路径,因为这将是根据表格的大小和数量以及您的实体之间的关系,这是很乏味的。
- 首先,不要使用新的标识符映射生成器(例如使用
false
)。 - 确认一切正常,即是现状。所有
@GeneratedValue
注释使用GenerationType.IDENTITY
。 - 更改为使用标识符映射生成器(例如,使用
true
)。 ,即现状。
此时,您不必更改数据库中的任何内容,来自备份。你所做的全部都是Java代码的移植,这样对于新实体,你可以使用新的标识符映射,并保留现有实体的旧方式。
从这一点转发,我建议一次迁移一个实体。
- 更改java类以使用由
hibernate_sequences
表支持的命名序列生成器。
- 确定实体数据的 MAX(ID),并在
hibernate_sequences $ c $中设置适当的下一个id值c>表中指定该实体的命名标识符。
- 这里单调乏味的部分是您需要删除与此实体现有的 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.
- First, don't use the new identifier mapping generators (e.g. use
false
). - Verify everything works, aka status-quo.
- Change all your
@GeneratedValue
annotations to useGenerationType.IDENTITY
. - Change to use identifier mapping generators (e.g. use
true
). - 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.
- Change the java class to use a named sequence generator backed by the
hibernate_sequences
table. - 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. - 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
orIDENTITY
but instead most likely something likeBIGINT
orINT
. 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屋!