【问题标题】:JPA Managed entities merge operations without cascade options没有级联选项的 JPA 托管实体合并操作
【发布时间】:2013-08-22 09:50:08
【问题描述】:

我正在尝试更新事务中的实体,首先我使用其主键选择实体,然后延迟加载其子实体并通过 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;
   }
 });

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

【问题讨论】:

  • 发布代码而不是描述它。并定义什么是非关系表。
  • @JBNizet,感谢您的回复,我也添加了相关代码。

标签: hibernate transactions jpa-2.0


【解决方案1】:

好的,所以您会惊讶地发现,对实体所做的更改甚至无需调用 merge() 或任何其他方法即可持久保存。

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

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

阅读this part of the documentation了解更多详情。

【讨论】:

  • 感谢您解除了我的疑虑。因此,即使我没有为父实体类调用合并,对实体类所做的所有更改也会在事务提交时持久化到数据库中。
  • 是的,你明白了。一旦实体管理器关闭(通常在事务结束时发生),实体就会分离,并且对这些实体所做的更改不再透明地持久化。
  • @JBNizet 能否请您帮忙解决这个问题link。我一直在阅读您对类似问题的许多答案,但我自己找不到解决方案。
猜你喜欢
  • 2013-11-13
  • 2012-06-17
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 2016-02-10
  • 1970-01-01
相关资源
最近更新 更多