Spring JPA保存Product报DataIntegrityViolationException异常
问题根因
异常明确指向com.spring.entity.Product.cd属性非空校验失败,核心触发逻辑如下:
Product实体的cd字段配置了@ManyToOne(optional = false),Hibernate持久化时会强制校验该字段不能为null、不能指向未持久化的临时态对象- 双向一对多关联中,
Product侧(多对一方)是关联关系的持有方,仅在CustomerDetails的product集合中添加Product实例、不手动给Product的cd字段赋值所属CustomerDetails对象时,级联保存Product阶段就会出现cd属性为null的情况 - 现有
Product类的两个公开构造方法均未包含cd属性的赋值逻辑,进一步放大了漏赋值的概率
修复方案
- 保存前手动维护双向关联关系,保证每个Product实例的cd属性指向所属的CustomerDetails对象,参考实现如下:
// 初始化客户 CustomerDetails customer = new CustomerDetails("张三", "zhangsan@demo.com", "北京市", "13800138000"); // 初始化商品 Product laptop = new Product("笔记本电脑", "联想", 5999.0); Product mouse = new Product("无线鼠标", "罗技", 199.0); // 维护双向关联(原有代码缺失这部分逻辑) Set<Product> productSet = new HashSet<>(); laptop.setCd(customer); productSet.add(laptop); mouse.setCd(customer); productSet.add(mouse); customer.setProduct(productSet); // 调用Repository保存即可正常持久化 customerRepository.save(customer);
- 优化实体类设计,减少漏赋值风险。可以在
CustomerDetails类中新增统一维护关联关系的工具方法,避免每次业务代码重复写关联逻辑:
// 新增到CustomerDetails类中 public void addProduct(Product product) { if (this.product == null) { this.product = new HashSet<>(); } // 自动维护多对一侧的关联指向 product.setCd(this); this.product.add(product); }
后续业务代码中直接调用customer.addProduct(xxx)即可完成关联赋值,无需手动操作Product的cd字段。
- 校验业务约束合理性:如果业务允许商品不绑定所属客户,直接删除
@ManyToOne注解中的optional = false配置,关闭该字段的非空校验即可;如果业务要求商品必须绑定客户,保留该配置,确保关联赋值逻辑正确即可。
内容的提问来源于stack exchange,提问作者user1712
相关产品推荐
相关产品推荐

