JPA Pitfalls (4): Relationship Owner

This blog article is part of a “series of blog articles” about common pitfalls using JPA and ways to avoid them. In this article, we describe issues with bidirectional relationships.

In a bidirectional relationship, each entity has a relationship field or property that refers to the other entity. In JPA a bidirectional relationship has an owing and an inverse side. The inverse side is the one having the mappedBy element in the relationship annotation. In the following example Employee is the owning side of the bidirectional Employee ↔ Department relationship.

@Entity 
public class Employee {
  @ManyToOne
  private Department department;
} 

@Entity 
public class Department {
  @OneToMany(mappedBy="department")
  private Set<Employee> employees;
}

According to the JPA spec “Bidirectional relationships … will be persisted based on references held by the owning side of the relationship”. For the example above this means: defining the relation by setting the department on the employee instance will result in the relationship being persisted. But if the relationship change is only on the inverse side, e.g. adding an employee to the department’s set of employees, there is no guarantee that this relationship is stored in the database.

// OK
emp.setDepartment(dept); 
// Might not be stored in the database
dept.addEmployee(emp); 

Recommendation: Make sure the owning side is changed, when modifying a bidirectional relationship.

You can find an example of this pitfall and its solution in the class RelationshipOwnerExperiment in this project: https://github.com/akquinet/jpapitfalls.git.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.