GenerationType.SEQUENCE生成已存在的ID

时间:2016-10-19 11:14:43

标签: spring hibernate jpa spring-boot

我有一个春季启动应用程序,它已经在线运行了几个月,直到今天仍然没有任何问题。我有一个具有id生成类型序列的实体:

@Entity
@ComponentScan
public class MyEntity {
    /**
     * 
     */
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;
}

从今天开始,我在创建和存储新实体时遇到错误:

Unique index or primary key violation: "PRIMARY_KEY_D92 ON PUBLIC.MyEntity(ID) VALUES (3713, 250)"; SQL statement:

每次发生此错误时,生成的ID(本例中为3713)已存在于数据库中。那么为什么GenerationType.SEQUENCE突然产生了已存在的ID?

修改

我使用H2数据库版本1.4.191

1 个答案:

答案 0 :(得分:3)

我遇到过Hibernate的这个问题,但我们有明确的@SequenceGenerator注释。问题是JPA中的默认SequenceGenerator的allocationSize为50,其中默认数据库序列的增量为1.这两个值必须相同。一种解决方案是定义SequenceGenerator并显式设置allocationSize。

@SequenceGenerator(name = "my_entity_gen", sequenceName = "my_entity_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_entity_gen")

生成器必须是唯一的,除非您希望两个表共享它们。

另一种解决方案是使用不同的生成策略。

@GeneratedValue(strategy = GenerationType.IDENTITY)

如果数据库已经知道在插入时查询序列,则通常会这样做,除非您在表之后明确创建了序列。

第一种方法将针对每个插入触发对数据库的两个查询,因此几乎肯定效率较低。