Reputation: 363
i am trying to update an Entity inside a transaction, first i select the entity using its primary key, then lazily loaded its child entities and made changes to its properties through setter methods. After that when i merge the parent object, automatically all its child objects with OneToMany relations gets updated. Although this is the required functionality, but i am little confused with this behavior because i didn't specified any cascade options for the child entities. In order to make sure, i even tried a non-relational table, just queried using find JPAQL and changed its properties. When the transaction commited after the merge operation of the main entity, this non-relational entity also gets updated along with others. I am not sure this is the correct behavior, or its the problem of understanding the JPA and merge operation inside transactions.
My Parent class
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;
}
My Child class
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;
}
Non-Relational Entity is just an Entity class without any relations with this selected entity classes. I added it to just to check whether the updations happened due to any relations specified in the entity classes(Even without cascade options).
My Transactional Update function.
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;
}
});
so the final outcome after merging and transaction commit is that, all the tables(Student, Subjects and Category)updated.
Upvotes: 0
Views: 1767
Reputation: 692043
OK, so you're surprised that changes made to entities are persisted without even calling merge()
or any other method.
That's one of the main points of JPA/Hibernate and attached entities: you modify them, and since they're attached to a persistence context, all these changes are transparently persisted when needed (at most, at the end of the transaction).
merge()
is used to copy the state of a detached entity to an attached one.
Read this part of the documentation for more details.
Upvotes: 3