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提供程序时使用序列生成器的最佳做法是什么?
是的,你的分析是正确的。 您正确识别了问题(我们遇到了类似的问题)。 而且......如果你要把它用于制作,别忘了:
@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