Question

Short version:

Lets say I have a One to many relation ship, between Parent and Child. Now in the Java code, is the best practice to read the parent object (get it from the database), and apply some method called addChild in it, or I directly create a child and persist it without reading the Parent ?

Long version

Lets say we have this Parent and Child (from http://en.wikibooks.org/wiki/Java_Persistence/OneToMany)

@Entity
public class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  ...
  @OneToMany(mappedBy="owner")
  private List<Phone> phones;
  ...
}


@Entity
public class Phone {
  @Id
  private long id;
  ...
  @ManyToOne(fetch=FetchType.LAZY)
  @JoinColumn(name="OWNER_ID")
  private Employee owner;
  ...
}

And now consider I have a web page where employee can add a phone number. So I already have the id of the parent Employee but I don't have the complete Employee object.

1- I get the whole Employee object from the database (by JPA mapping of course). Then I apply the method employee.addPhone(Phone phone) or something like that. This leads to two queries.

2- I create the phone object, and a wrong employee object that contains only the id of the employee and I persist ?

What are the best practices for this ?

Was it helpful?

Solution

The best practice is to maintain both sides of the association. That makes sure you aren't working with an inconsistent graph of objects. It can, however, decrease the performance of the service, especially if all it does is creating a new Phone, linked to an Employee. Indeed, it will load the state of the employee and of all its existing phones.

Note that JPA only cares about the owner side of the association: setting the employee of the new Phone is sufficient to have the association created in database.

If you choose to go with the second solution, you shouldn't create a fake Employee object though. You should instead get an Employee reference from the EntityManager:

Employee e = em.getReference(Employee.class, employeeId);
Phone phone = new Phone();
phone.setEmployee(e);
em.persist(phone);

getReference() doesn't generate any SQL query. It returns an uninitialized proxy, which is all you need. The advantage is that if the method ends up being more complex, and calls any method of the employee, then the actual state of the employee will be loaded.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top