You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate逻辑删除后插入同主键实体报重复键错误如何解决

问题根源

你遇到的报错并不是你新增的constraint_country联合约束导致的,而是违反了表中country_pkey主键约束:你当前的表结构将code设为主键,主键本身要求该字段值全局唯一,和你是否逻辑删除没有关系——逻辑删除只是给date_deleted赋值,旧记录的code值仍然存在于表中,新增同code的记录自然会触发主键冲突。

解决方案

1. 优先方案:调整表结构+配套Hibernate注解

要实现「逻辑删除后可新增同code记录,同时保证未删除的code唯一」,首先要调整表的主键设计,再配合对应索引规则:

表结构修改

  • 新增无业务含义的字段作为主键,比如自增id字段
  • 删除原code的主键约束
  • 新建部分唯一索引(PostgreSQL支持该特性),只限制date_deleted IS NULL的记录code唯一,比你之前加的联合唯一约束更符合需求:
CREATE TABLE public.country(
    id int8 NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY, -- 新增主键
    code bpchar(2) NOT NULL,
    description bpchar(50) NULL,
    date_deleted timestamp NULL
);
-- 新增部分唯一索引,保证未删除的code唯一
CREATE UNIQUE INDEX idx_country_unique_code ON country (code) WHERE date_deleted IS NULL;

Hibernate实体类修改

对应调整实体类的注解配置即可,原有逻辑删除的@SQLDelete、@Where注解可以保留:

@Entity
@Table(name = "Country")
@SQLDelete(sql = "UPDATE Country SET date_deleted=NOW() WHERE id = ?") // 注意这里条件改为新主键id
@Where(clause = "date_deleted is NULL")
// 如果要让Hibernate自动生成上述部分唯一索引,可以用Hibernate专有注解:
@org.hibernate.annotations.Table(appliesTo = "Country", indexes = {
    @Index(name = "idx_country_unique_code", 
           columnNames = {"code"}, 
           unique = true)
})
public class Country {
    // 新增主键字段
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "code", nullable = false)
    private String code;

    @Column(name = "description")
    private String description;

    @Column(name = "date_deleted")
    private Date date_deleted;
    // 其余逻辑不变
}

2. 备选方案:逻辑删除时修改旧记录code

如果无法调整表结构,可以修改@SQLDelete的逻辑,删除时给旧记录的code加上删除标记,避免和新记录冲突,该方案无需修改表结构但会污染业务字段,仅作为临时方案:

// 逻辑删除时拼接删除标记到旧code上,释放code的占用
@SQLDelete(sql = "UPDATE Country SET date_deleted=NOW(), code = CONCAT(code, '_del_', EXTRACT(EPOCH FROM NOW())) WHERE code = ?")

内容的提问来源于stack exchange,提问作者Mathias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 11:57:01