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

JPA单仓库保存关联对象失败:id_hour字段非空异常

问题解决:Hibernate保存关联对象时id_hour为空报错

问题核心原因

报错本质是双向关联的关系未正确维护:

  • Hour与RegularHour是一对多双向关联,RegularHour是关联的拥有方(@JoinColumn定义在此类中,Hibernate以拥有方的关联状态为准)
  • 创建对象时,仅给Hour的regularHours列表添加了RegularHour实例,但未给每个RegularHour设置对应的hour属性,导致插入regular_hour表时外键id_hour无值,触发非空约束错误。

解决方案

1. 在Hour类中添加关联维护方法

手动维护双向关联是最可靠的方式,在Hour中添加方法确保双方关联同步:

@Setter @Getter @Builder
@AllArgsConstructor @NoArgsConstructor
@Entity
@Table(name = "hour")
public class Hour {
    // 原有属性保持不变
    
    // 替代直接操作regularHours列表,用此方法添加关联
    public void addRegularHour(RegularHour regularHour) {
        this.regularHours.add(regularHour);
        regularHour.setHour(this); // 关键:给RegularHour设置对应的Hour引用
    }

    // 可选:添加移除关联的方法
    public void removeRegularHour(RegularHour regularHour) {
        this.regularHours.remove(regularHour);
        regularHour.setHour(null);
    }
}

2. 创建对象时使用维护方法

构建对象流程中,调用addRegularHour替代直接操作列表:

// 构建RegularHour实例
RegularHour regularHour = RegularHour.builder()
        .weekday(1)
        .periodBegin("07:00")
        .periodEnd("18:00")
        .build();

// 构建Hour实例并初始化列表
Hour hour = Hour.builder()
        .twentyfourseven(false)
        .regularHours(new ArrayList<>())
        .build();

// 用维护方法建立双向关联
hour.addRegularHour(regularHour);

// 构建Location实例
Location location = Location.builder()
        .id("LOC001")
        .hour(hour)
        .build();

// 执行保存
locationRepository.save(location);

3. 可选:自定义Lombok Builder自动维护关联(进阶)

如果依赖Lombok的@Builder,可自定义Builder自动同步关联(注意此方式需注意Builder生命周期):

@Setter @Getter
@AllArgsConstructor @NoArgsConstructor
@Entity
@Table(name = "hour")
public class Hour {
    // 原有属性不变
    
    @OneToMany(mappedBy="hour", cascade = CascadeType.ALL)
    private List<RegularHour> regularHours = new ArrayList<>();

    // 自定义Builder
    public static class HourBuilder {
        private List<RegularHour> regularHours = new ArrayList<>();

        public HourBuilder regularHour(RegularHour regularHour) {
            this.regularHours.add(regularHour);
            regularHour.setHour(this.build());
            return this;
        }

        public HourBuilder regularHours(List<RegularHour> regularHours) {
            regularHours.forEach(rh -> rh.setHour(this.build()));
            this.regularHours = regularHours;
            return this;
        }
    }
}

验证效果

修改后执行保存操作,Hibernate会先插入hour表获取自动生成的id_hour,再插入regular_hour时自动填充该外键值,即可解决非空报错问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:24:52