我有一个项目,每个
Student
都可以由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);
}
}
学生:
@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 错误,因为测试人员的名字神奇地为空?!? 如果我从列中删除
nullable = false
,测试仪实体将被保存,但名称列中为空...
我到底做错了什么?
请不要建议先保存测试器,这没有帮助,因为我想了解我的代码有什么错误。
评论中的回答。根据 Spring 文档,假设学生已经存在,因为它有一个 id:
默认情况下,Spring Data JPA 首先检查是否存在 非原始类型的版本属性。如果存在,则该实体是 如果该属性的值为 null,则视为新的。如果没有这样一个 版本属性 Spring Data JPA 检查标识符属性 给定的实体。如果标识符属性为 null,则该实体 被认为是新的。否则,就认为它不是新的。
这可以通过添加版本列或使用控制实体是否是新实体的 @Transient 标志来解决(在链接文档中更详细地描述)。
或者,可以在没有 Spring 的情况下使用实体管理器的 persist 方法。