Search code examples
jpaejbeclipselink

Why do I need to set the entities both ways in JPA


I have two following entities:

@Entity
public class Pilot implements Serializable {
....
    @ManyToOne
    @JoinColumn(name = "FLIGHT_ID")
    private Flight flight;
}

and

@Entity
public class Flight implements Serializable {
....
    @OneToMany(mappedBy = "flight")
    private List<Pilot> pilots;
}

I am using an EJB to add a pilot to a flight:

public void addPilotToFlight(String pilotId, String flightId) {
    <code to find Flight f>
    <code to find Pilot p>
    p.setFlight(f);
    f.getPilots().add(p); // Why do I need this one?
}

My confusion is why do I need to link objects both ways?

I have tried the code with and without the f.getPilots().add(p); part, in DB it looks the exact same. However, when I try to use f.getPilots(); for the same flight entity object, it shows only if I had done the above both-way linking. Could anyone please shed some light on this? I'd be very grateful. Thanks in advance.


Solution

  • Your question seems aimed at asking why you have to maintain both sides of a bidirectional relationship, which is a common question and source of confusion.

    CMP 2.0 tried to perform relationship maintenance and magic behind the scenes, but the overhead and lack of control was a problem (IMO) and it was not included in JPA. Instead, JPA entities are meant to be plain old java objects. That means if you want changes made to one side of a relationship to be reflected in the other, you must make them yourself.

    The confusion will be that if you modify one side of a relationship and not the other, sometimes the database will get updated correctly, sometimes not, and sometimes both sides will show the change. It all depends on which side you change, and how the entities are cached and refreshed from the database. Changes to the owning side are persisted to the database, and JPA allows for caching, so the non-owning side may not reflect these changes until it is refreshed from the database.

    The best practices is that any change you make to one side should be made to the other by the application if you want your object model to remain in sync with the database.