JHipster集成测试出现jakarta.validation.ConstraintViolationException:Category实体ID非空校验失败
嘿,看起来你在JHipster项目的集成测试里踩了个坑——Category实体保存时触发了非空校验失败,明明数据库里ID字段已经设了自增,结果还是报ID不能为null。我之前也碰到过类似问题,给你梳理下排查和解决的思路:
先查实体类的ID注解配置!
你贴的实体代码没写完,但十有八九是ID字段的JPA注解没配对。正常JHipster生成的自增ID应该是这样的:
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 这个是核心! @Column(name = "id", nullable = false) private Integer id; // 注意和数据库的INT类型对应,别用Long
要是你没加@GeneratedValue,或者策略选错了,Hibernate根本不知道要让数据库帮你生成ID,persist的时候ID还是null,自然触发@NotNull的校验了。
确认Liquibase的自增配置真的生效了
你的Liquibase脚本里写了autoIncrement="true",但不同数据库的自增实现不一样,比如PostgreSQL需要序列,MySQL是AUTO_INCREMENT。咱们可以手动去测试数据库里看看category表的结构:
- MySQL的话,看ID字段的Extra列是不是显示
auto_increment - PostgreSQL的话,查下有没有对应的序列,或者ID字段是不是
SERIAL/IDENTITY类型
要是配置没生效,那数据库也不会自动生成ID,问题自然还在。
检查测试代码里的实体创建逻辑
你测试里调用了CategoryResourceIT.createEntity(),别忘了确认这个方法创建Category的时候没手动设置ID——自增ID本来就该数据库生成,手动设值反而可能搞乱。另外,测试用的EntityManager配置有没有问题?会不会没开启自动生成ID的上下文?
处理Bean Validation的校验时机问题
这个异常是Bean Validation在persist之前触发的——毕竟SQL还没执行,这时候ID确实是null,要是ID字段加了@NotNull,校验肯定过不了。这种情况咱们有两个方向:
- 给ID字段同时加
@Null和@NotNull:@Null允许persist前ID为空,@NotNull保证持久化后ID有值,不过更推荐用前面说的@GeneratedValue让Hibernate处理,从根源解决。 - 临时关闭测试的Bean Validation?但这是治标不治本的办法,还是优先调整实体配置。
给你个具体的修复示例
假设你的Category实体ID注解缺了@GeneratedValue,补上之后应该是这样:
@Entity @Table(name = "category") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Category implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Integer id; // 其他字段:sex、nat这些的注解和方法... }
补完之后重新跑测试,要是还不行,就开Hibernate的SQL日志,看看插入语句里有没有ID字段,数据库是不是真的生成了ID。
内容来源于stack exchange

