Spring-boot是否改变了ids的自动增量通过@GeneratedValue的方式?

时间:2018-03-12 17:29:54

标签: spring hibernate jpa spring-boot spring-data-jpa

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 ,我能够生成单独的自动增量序列,这意味着我可以获得Car 1 作为主键,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 发生变化,解释了这种情况?

4 个答案:

答案 0 :(得分:12)

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无法按预期工作的原因。

答案 1 :(得分:1)

正如安德鲁在评论中指出的那样,如果您不希望在其他表中创建值时增加ID,则可以这样指定ID:

@Id
@GeneratedValue(
    strategy= GenerationType.AUTO,
    generator="native"
)
@GenericGenerator(
    name = "native",
    strategy = "native"
)
private Long id;

这样做将使每个表具有以1,2,3 ...开头的唯一ID,以此类推。

答案 2 :(得分:0)

如果您需要一种快速且不合时宜的解决方案来防止此问题的发生:

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中包含的旧功能。

请注意,这可能不是最好的解决方案,但从短期来看非常有用

答案 3 :(得分:0)

您可以使用

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

使用MySQL自动增量。