JPA托管实体在没有级联选项的情况下合并操作



我正在尝试更新事务中的实体,首先我使用其主键选择实体,然后延迟加载其子实体,并通过setter方法更改其属性。之后,当我合并父对象时,它的所有具有OneToMany关系的子对象都会自动更新。虽然这是必需的功能,但我对这种行为有点困惑,因为我没有为子实体指定任何级联选项。为了确保这一点,我甚至尝试了一个非关系表,只是使用findJPAQL查询并更改了它的属性。当事务在主实体的合并操作之后提交时,这个非关系实体也会与其他实体一起更新。我不确定这是否是正确的行为,也不确定这是理解事务中的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;
   }
 });

因此,合并和事务提交后的最终结果是,所有表(Student、Subject和Category)都更新了。

好吧,所以您会惊讶地发现,对实体所做的更改甚至在不调用merge()或任何其他方法的情况下都会被持久化。

这是JPA/Hibernate和附加实体的要点之一:您可以修改它们,因为它们附加到持久性上下文,所以所有这些更改在需要时(最多在事务结束时)都会透明地持久化。

merge()用于将分离实体的状态复制到附加实体。

有关更多详细信息,请阅读本部分文档。

相关内容

最新更新