Hibernate单向OneToMany外键非空约束下如何直接插入关联外键值
问题根源
你遇到的报错是单向@OneToMany关联的默认处理逻辑导致的:Hibernate处理单向一对多关联时,会先插入子表(review)记录,此时外键course_id还未赋值,后续再执行update语句回填外键值,自然就触发了数据库的非空约束。
解决方案(推荐:改为双向关联)
这种方案可以从根本上避免额外的update语句,插入review时直接携带course_id值:
1. 修改Course实体类
- 移除
@OneToMany上的@JoinColumn注解,新增mappedBy属性指定关联由Review端的course字段维护 - 修改
addReview方法,手动给review对象设置关联的course实例
@Data @Entity @Table(name = "course") public class Course { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "course_id") private int id; @Column(name = "name") private String name; // 新增mappedBy,移除@JoinColumn @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL, mappedBy = "course") private List<Review> reviews; public Course(){} public Course(String name){ this.name = name; } public void addReview(Review review){ if(this.reviews == null){ this.reviews = new ArrayList<>(); } // 给review设置关联的course review.setCourse(this); this.reviews.add(review); } }
2. 修改Review实体类
新增Course类型的字段,添加@ManyToOne和@JoinColumn注解,指定外键非空:
@Data @Entity @Table(name = "review") public class Review { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "review_id") private int reviewId; @Column(name = "rating") private int rating; // 新增关联字段,指定外键非空 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "course_id", nullable = false) private Course course; public Review(){} public Review(int rating){ this.rating = rating; } }
3. 原有业务代码无需修改
你之前写的添加评论的代码可以直接运行,Hibernate执行的SQL会变为:
Hibernate: insert into review (rating, course_id) values (?, ?)
直接在插入时就携带了course_id值,完美兼容数据库的非空约束。
替代方案(保留单向关联)
如果你不想改造为双向关联,可以直接在Course类的@JoinColumn注解上添加nullable = false属性:
@OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL) @JoinColumn(name = "course_id", nullable = false) private List<Review> reviews;
该配置会告知Hibernate外键不允许为空,插入review时会自动填充course_id值,也可以解决非空约束报错问题。
内容的提问来源于stack exchange,提问作者fahmiduldul
相关产品推荐
相关产品推荐

