Postgresql 重复的键值违反了唯一约束;冬眠;博士后的例外

Postgresql 重复的键值违反了唯一约束;冬眠;博士后的例外,postgresql,hibernate,jpa,spring-data,Postgresql,Hibernate,Jpa,Spring Data,在Postgres中持久化新实体时,基于My Spring Data(JPA/Hibernate)的应用程序在负载增加时引发以下异常: org.postgresql.util.PSQLException:错误:重复的键值违反唯一约束“hibernate\u sequences\u pkey” id的策略定义如下: @Id @GeneratedValue(strategy = GenerationType.TABLE) @Column(name = "ID") public Long getId(

在Postgres中持久化新实体时,基于My Spring Data(JPA/Hibernate)的应用程序在负载增加时引发以下异常: org.postgresql.util.PSQLException:错误:重复的键值违反唯一约束“hibernate\u sequences\u pkey”

id的策略定义如下:

@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "ID")
public Long getId() {
    return id;
}
我知道这一策略对博士后来说并不是完美的解决方案,但这是否是上述例外的原因呢


负载是使用Apache Camel路由生成的,拆分器在多个线程上并行运行insert。

经过一些测试后,问题似乎确实是由
strategy=GenerationType.TABLE
引起的。更改为
strategy=GenerationType.SEQUENCE
后,上述重复键的问题消失了

@Id
@SequenceGenerator(name = Consts.VEHICLE_ATTR_ID_SEQ,
        sequenceName = Consts.VEHICLE_ATTR_ID_SEQ,
        allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,
        generator = Consts.VEHICLE_ATTR_ID_SEQ)
@Column(name = "ID", updatable = false)
public Long getId() {
    return id;
} 

从Hibernate 4迁移到5.3.1(Wildfly 14.0.1)时,我还遇到了与“重复键值违反唯一约束”Hibernate_sequences_pkey“错误消息相关的问题。在调查Hibernate 5.3.1的源代码后,我可以使用
策略=GenerationType.TABLE
(我也知道这个策略不是完美的解决方案)。主要问题是TableGenerator类。要解决这个问题,除了使用GenericGenerator注释外,还应该使用GenericGenerator注释,例如:

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = TableGenerator.DEF_TABLE)
@GenericGenerator(name = TableGenerator.DEF_TABLE, strategy
        = "org.hibernate.id.enhanced.TableGenerator", parameters = {
        @Parameter(name = TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY, value = "true")})
@Column(name="id")
private Integer id;
TableGenerator.CONFIG\u preference\u SEGMENT\u PER\u ENTITY
参数设置为真值(因为它默认为假值,在这种情况下Hibernate将使用Hibernate\u sequences表中的“默认”段名称而不是表名称)。 您还应该将
hibernate.model.generator\u name\u as\u sequence\u name
属性设置为假值,以便只有一个hibernate\u sequences表,否则,hibernate将使用生成器名称作为序列表的名称(根据更改)。另外(但不是必需的)您可以将
hibernate.id.generator.storaged\u last\u used
属性也设置为假值(更改),因为:

为了符合JPA规范,存储的值 Hibernate 5.3在
javax.persistence.TableGenerator
是最后生成的值。 以前版本的Hibernate存储了下一个要修改的值 用过

要向后兼容,请使用新设置, 上次使用的hibernate.id.generator.storaged已被引入 提供了返回到旧的休眠行为的机会。 迁移到5.3并使用@TableGenerator的现有应用程序 将上次使用的
hibernate.id.generator.storaged\u设置为
false