Hibernate @ManyToOne级联PERSIST异常:Tester的name为null问题排查
问题:单向Many-to-One级联保存时Tester的name字段为null的原因
我有一个项目,每个Student可由一个Tester测试,单个Tester可测试多个Student,需要Student关联对应的Tester,这是单向Many-to-One关系。
Tester实体代码
@Entity public class Tester { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String name; public Tester(String name) { this.name = name; } protected Tester(){} public String getName() { return this.name; } @Override public String toString() { return String.format("Tester [id=%s, name=%s]", this.id, this.name); } }
Student实体代码
@Entity public class Student { @Id private Long id; //this shouldn't be auto incremented @Column(nullable = false) private int age; @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name = "tester_id") private Tester tester; public Student(Long id, int age, Tester tester) { this.id = id; this.age = age; this.tester = tester; } protected Student(){} public int getAge() { return this.age; } public Tester getTester() { return this.tester; } @Override public String toString() { return String.format("Student [id=%s, age=%s, tester=%s]", this.id, this.age, this.tester); } }
测试代码
Tester tester = new Tester("Tester"); Student student = new Student(1L, 27, tester); this.studentRepository.save(student);
我期望通过级联操作同时保存两个实体,但却出现SQL错误,原因是Tester的name字段为null;若移除Tester中@Column(nullable=false)属性,Tester虽能保存但name字段仍为null。请问我的代码哪里存在错误?请勿建议先保存Tester,我想明确代码本身的问题。
解答
你的问题出在Tester类缺少name字段的setter方法。
Hibernate执行CascadeType.PERSIST级联持久化时,处理关联实体的逻辑是:
- 先调用关联实体的无参构造函数创建实例
- 通过反射调用属性对应的setter方法完成赋值
- 最后执行数据库插入操作
你的Tester类仅通过带参构造函数初始化name,但没有提供setName()方法,Hibernate无法为反射创建的Tester实例设置name值,最终导致插入数据库时name字段为null,触发nullable=false的约束错误。
只需给Tester类添加name的setter方法即可解决问题:
public void setName(String name) { this.name = name; }
添加后,Hibernate就能正常为Tester实例注入name值,级联保存时两个实体都会正确写入数据库。
内容的提问来源于stack exchange,提问作者user14647130
相关产品推荐
相关产品推荐

