Krishna
Krishna

Reputation: 363

JPA Managed entities merge operations without cascade options

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

Answers (1)

JB Nizet
JB Nizet

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

Related Questions