JPA 2 @SequenceGenerator @GeneratedValue产生唯一的约束违规

问题概述

在看似随机的时候,我们得到一个异常“postgresql重复键违反了唯一约束”。 我确实认为我知道我们的问题是什么,但我不想在没有可重复的测试用例的情况下对代码进行更改。 但是由于我们无法在任何环境中复制它,除了随机生产外,我要求SO提供援助。

在这个项目中,我们有多个postgres数据库,并为每个数据库中的每个表配置一个主键序列。 这些序列是这样创建的:

create sequence PERSONS_SEQ;
create sequence VISITS_SEQ;
etc...

我们使用这些序列为这些实体生成主键:

@Entity
@Table(name = "visits")
public class Visit {
  @Id
  @Column(name = "id")
  @SequenceGenerator(name = "seq", sequenceName = "visits_seq")
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
  private int id;
  ...
}

@Entity
@Table(name = "person")
public class Person {
  @Id
  @Column(name = "id")
  @SequenceGenerator(name = "seq", sequenceName = "persons_seq")
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
  private int id;
  ...
}

分析

我想我认识到这个配置有两个问题:

1)两个@SequenceGenerator指定相同的名称属性,即使它们应该映射到不同的数据库序列。

2)@SequenceGenerator的分配大小属性默认为50(我们使用hibernate作为JPA提供者),所以我认为创建序列语法应该指定序列应该增加多少,特别是50来匹配分配大小。

基于这个猜测,我认为代码应该修改为这样的:

create sequence PERSONS_SEQ increment by 50;
create sequence VISITS_SEQ increment by 50;
etc...

@Entity
@Table(name = "visits")
public class Visit {
  @Id
  @Column(name = "id")
  @SequenceGenerator(name = "visits_seq", sequenceName = "visits_seq")
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "visits_seq")
  private int id;
  ...
}

@Entity
@Table(name = "person")
public class Person {
  @Id
  @Column(name = "id")
  @SequenceGenerator(name = "persons_seq", sequenceName = "persons_seq")
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "persons_seq")
  private int id;
  ...
}

我只是测试一下,而不是在SO上提出这个问题,但是,我们再也没有能够在任何其他环境中重现这个生产问题。 即使在生产中,唯一的约束违规只发生在看似随机的时间。

问题:

1)我在分析修改这个独特的违反约束条件的变化时是否正确?

2)使用hibernate作为JPA提供程序时使用序列生成器的最佳做法是什么?


  • 是的,你的分析是正确的。 您正确识别了问题(我们遇到了类似的问题)。 而且......如果你要把它用于制作,别忘了:

  • 或者手动为新的序列发生器生成序列表,并使用正确的初始值/初始ID(否则hibernate将从1开始,您将再次获得)
  • 或者在代码中设置该值(在@SequenceGenerator检查initalValue )。
  • 我无法列举最佳实践,但我想你可以降低50的限制。我也没有PostgreSQL的经验,但是在MySQL中你有一个简单的seq表。 发生器和休眠使得整个东西。


  • 我也有类似的问题。 在我的情况下,我直接通过SQL导入数据。 这导致了'hibernate_sequence'的问题。 hibernate_sequence是由id 123,但我的表中有id大于123的行。

    链接地址: http://www.djcxy.com/p/16139.html

    上一篇: JPA 2 @SequenceGenerator @GeneratedValue producing unique constraint violation

    下一篇: System calls : difference between sys