Spring-boot 是不是改变了通过@GeneratedValue 自动增加 id 的方式?
Posted
技术标签:
【中文标题】Spring-boot 是不是改变了通过@GeneratedValue 自动增加 id 的方式?【英文标题】:Has Spring-boot changed the way auto-increment of ids works through @GeneratedValue?Spring-boot 是否改变了通过@GeneratedValue 自动增加 id 的方式? 【发布时间】:2018-08-20 19:50:09 【问题描述】:Spring-Boot 2.0.0 似乎修改了 Hibernate 的自动配置方式。
让我们假设两个简单且独立的 JPA 实体:
@Entity
class Car
@Id
@GeneratedValue
private long id;
//....
@Entity
class Airplane
@Id
@GeneratedValue
private long id;
//....
之前,使用 Spring-Boot 1.5.10,我能够生成单独的自动增量序列,这意味着我可以通过 1 获得Car
作为主键,Airplane
也以 1 作为主键。
它们之间没有相关性,例如没有共享序列。
现在,使用 2.0.0,当我依次创建第一个 Car
和第一个 Airplane
时,汽车将获得 1 作为 id 和飞机得到 2。
看来他要处理GeneratedType.AUTO
,也就是@GeneratedValue
注解源中指定的“默认使用”。
但是,我的推理似乎停在这里,因为GeneratedType.AUTO
也被设置为 1.5.10 的默认值。
满足我期望的一个简单解决方法是指定 IDENTITY
生成策略类型,如下所示:
@Entity
class Car
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
//....
@Entity
class Airplane
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
//....
我无法解释这种行为。
Spring-boot 2.0.0 发生了什么变化,解释了这种情况?
【问题讨论】:
我怀疑这是 Hibernate 5.0.x(Spring Boot 1.5 使用)和 Hibernate 5.2.x(Spring Boot 2.0 使用)之间的区别。 使用 GenerationType.IDENTITY 不是解决方法。我认为,在这种情况下,这是最佳做法。 感谢您提供此信息。为了解决这个问题,我将hibernate.id.new_generator_mappings
属性设置为false
(在spring-boot 1.5 中设置),因为我使用的是mysql。
【参考方案1】:
Spring Boot 2.0 使用 Hibernate 5.2 (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes)。
从 5.2 开始,Hibernate 更改了其GeneratedType.AUTO
策略。任何本身不支持序列的数据库(例如 MySQL),它们都使用 TABLE 生成器而不是 IDENTITY。 (https://hibernate.atlassian.net/browse/HHH-11014)
这就是GeneratedType.AUTO
无法按预期工作的原因。
【讨论】:
嗨敏,谢谢你...vladmihalcea.com/…【参考方案2】:你可以使用
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
使用 MySQL 自动增量。
【讨论】:
【参考方案3】:正如 Andrew 在评论中指出的那样,如果您不希望在其他表中创建值时增加 id,您可以像这样指定您的 ID:
@Id
@GeneratedValue(
strategy= GenerationType.AUTO,
generator="native"
)
@GenericGenerator(
name = "native",
strategy = "native"
)
private Long id;
这样做会使每个表都有其唯一的 id,以 1,2,3 ... 开头,依此类推。
【讨论】:
【参考方案4】:如果您需要一种快速的、非面向未来的解决方案来防止此问题的发生:
spring.jpa.hibernate.use-new-id-generator-mappings=false
,来自 Spring Boot 2 文档:
spring.jpa.hibernate.use-new-id-generator-mappings= # Whether to use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE.
这将阻止使用新生成器并保留 Spring boot 1.x.x 中包含的旧功能。
请注意,这可能不是最好的解决方案,但在短期内很有帮助
【讨论】:
【参考方案5】:默认情况下 spring-boot 使用自动并根据对象保存的顺序递增值。
要根据每个对象提供唯一的 id,请使用以下内容
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
【讨论】:
以上是关于Spring-boot 是不是改变了通过@GeneratedValue 自动增加 id 的方式?的主要内容,如果未能解决你的问题,请参考以下文章
GSEA - Gene set enrichment analysis 基因集富集分析原理与应用
使用 spring-boot:run 时是不是可以使用 spring-boot 命令行属性?
MAGENTA: Meta-Analysis Gene-set Enrichment of variaNT Associations