1.3.6. Working bi-directional links
First, keep in mind that Hibernate does not affect normal Java semantics. How did we create a link between a Person
and an Event
in the unidirectional example? We added an instance of Event
to the collection of event references, of an instance of Person
. So, obviously, if we want to make this link working bi-directional, we have to do the same on the other side - adding a Person
reference to the collection in an Event
. This "setting the link on both sides" is absolutely necessary and you should never forget doing it.
Many developers program defensive and create a link management methods to correctly set both sides, e.g. in Person
:
protected Set getEvents() {
return events;
}
protected void setEvents(Set events) {
this.events = events;
}
public void addToEvent(Event event) {
this.getEvents().add(event);
event.getParticipants().add(this);
}
public void removeFromEvent(Event event) {
this.getEvents().remove(event);
event.getParticipants().remove(this);
}
Notice that the get and set methods for the collection are now protected - this allows classes in the same package and subclasses to still access the methods, but prevents everybody else from messing with the collections directly (well, almost). You should probably do the same with the collection on the other side.
What about the inverse
mapping attribute? For you, and for Java, a bi-directional link is simply a matter of setting the references on both sides correctly. Hibernate however doesn't have enough information to correctly arrange SQL INSERT
and UPDATE
statements (to avoid constraint violations), and needs some help to handle bi-directional associations properly. Making one side of the association inverse
tells Hibernate to basically ignore it, to consider it a
mirror
of the other side. That's all that is necessary for Hibernate to work out all of the issues when transformation a directional navigation model to a SQL database schema. The rules you have to remember are straightforward: All bi-directional associations need one side as inverse
. In a one-to-many association it has to be the many-side, in many-to-many association you can pick either side, there is no difference.
Let's turn this into a small web application.