Postgresql 重复的键值违反了唯一约束;冬眠;博士后的例外
在Postgres中持久化新实体时,基于My Spring Data(JPA/Hibernate)的应用程序在负载增加时引发以下异常: org.postgresql.util.PSQLException:错误:重复的键值违反唯一约束“hibernate\u sequences\u pkey” id的策略定义如下: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(
@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