使用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
相关产品推荐
相关产品推荐

