我正在尝试更新事务中的实体,首先我使用其主键选择实体,然后懒惰地加载其子实体并通过setter方法更改其属性。之后,当我合并父对象时,自动将其所有具有OneToMany关系的子对象更新。虽然这是必需的功能,但我很少与此行为混淆,因为我没有为子实体指定任何级联选项。为了确保,我甚至尝试了一个非关系表,只是使用find JPAQL查询并更改了它的属性。当事务在主实体的合并操作之后提交时,该非关系实体也与其他实体一起更新。我不确定这是正确的行为,还是理解JPA和合并操作内部的操作的问题。
我的家长班
class Student
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Integer id;
private String name;
@OneToMany(mappedBy = "student")
private List<Subjects> subjects;
public Integer getId(){
return id;
}
public void setId(Integer id){
this.id=id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
我的孩子课
Class Subjects
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Integer id;
@JoinColumn(name = "student", referencedColumnName = "id", nullable = false)
@ManyToOne(optional = false)
private Student student;
public Integer getId(){
return id;
}
public void setId(Integer id){
this.id=id;
}
public String getCourse(){
return course;
}
public void setCourse(String course){
this.course=course;
}
非关系实体只是一个实体类,与所选实体类没有任何关系。我添加它只是为了检查更新是否由于实体类中指定的任何关系而发生(即使没有级联选项)。
我的交易更新功能。
Object obj1 = this.transactionTemplate.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
Category category=findById('2'); //Non-Related entity with Student or Subject
category.setName('new category');
Student student=findStudentById(1);
for(Subjects subjects:student.getSubjects()){
subjects.setCourse("test");
}
student.setName("student1");
entityManager.merge(student);
return true;
}
});
因此,合并和事务提交之后的最终结果是,所有表(学生,主题和类别)都已更新。
答案 0 :(得分:2)
好的,所以你会惊讶地发现对实体所做的更改是持久的,甚至没有调用merge()
或任何其他方法。
这是JPA / Hibernate和附加实体的要点之一:您修改它们,并且由于它们附加到持久性上下文,所有这些更改在需要时(最多,在事务结束时)透明地保留)。
merge()
用于将分离实体的状态复制到附加实体。