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

使用Swagger-UI新增Technology时触发PostgreSQL非空约束报错

问题分析与解决方案

1. 核心原因:数据库表结构未配置自增主键

你遇到的null value in column "id" of relation "technologies" violates not-null constraint异常,本质是PostgreSQL的technologies表中id列没有配置自增策略,导致Hibernate无法通过@GeneratedValue(strategy = GenerationType.IDENTITY)自动生成主键值,最终插入时传入null触发非空约束。

修复步骤:

修改数据库表结构,确保id列是自增主键:

-- PostgreSQL 10+推荐使用标准IDENTITY语法
ALTER TABLE technologies ALTER COLUMN id SET GENERATED ALWAYS AS IDENTITY;

-- 如果是PostgreSQL 9.x及更早版本,使用SERIAL类型
ALTER TABLE technologies ALTER COLUMN id TYPE SERIAL;

若表尚未创建,建表语句需包含自增配置:

CREATE TABLE technologies (
    id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    language_id INTEGER REFERENCES programming_languages(id)
);

2. 实体类优化建议

将id字段的基本类型int改为包装类Integer,避免基本类型默认值(0)可能引发的主键冲突或逻辑异常:

public class Technology {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private Integer id; // 替换为Integer包装类

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

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "language_id")
    private ProgrammingLanguage language;

    // 省略Getter、Setter方法
}

3. 业务逻辑代码的缺陷修复

你的add方法存在逻辑错误和效率问题:

  • 遍历所有Technology检查名称重复,数据量较大时效率极低
  • 缩进错误导致数据库无现有Technology记录时,technology.setName()不会执行

修复后的代码:

public void add(CreateTechnologyRequest technologyRequest) throws Exception {
    if(technologyRequest.getName().isBlank()) {
        throw new Exception("Please enter a name");
    }

    // 直接通过Repository查询重复名称,无需遍历全表
    if(technologyRepository.existsByNameIgnoreCase(technologyRequest.getName())) {
        throw new Exception("This name already exists.");
    }

    Technology technology = new Technology();
    technology.setName(technologyRequest.getName());

    // 通过Repository查询目标语言,避免遍历全表
    ProgrammingLanguage language = languageRepository.findByNameIgnoreCase(technologyRequest.getLanguageName());
    if(language != null) {
        technology.setLanguage(language);
    }

    technologyRepository.save(technology);
}

说明:需要在TechnologyRepository中添加existsByNameIgnoreCase(String name)方法,在ProgrammingLanguageRepository中添加findByNameIgnoreCase(String name)方法,Spring Data JPA会自动实现这些查询逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:31:07