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 的方式?的主要内容,如果未能解决你的问题,请参考以下文章

spring-boot用jackson改变json响应结构

GSEA - Gene set enrichment analysis 基因集富集分析原理与应用

使用 spring-boot:run 时是不是可以使用 spring-boot 命令行属性?

请教ORF 和 gene 的区别

MAGENTA: Meta-Analysis Gene-set Enrichment of variaNT Associations

Spring-boot入门资料