1.3.2. A unidirectional Set-based association
We'll add a collection of events to the Person
class. That way we can easily navigate to the events for a particular person, without executing an explicit query - by calling aPerson.getEvents()
. We use a Java collection, a Set
, because the collection will not contain duplicate elements and the ordering is not relevant for us.
We need a unidirectional, many-valued associations, implemented with a Set
. Let's write the code for this in the Java classes and then map it:
public class Person {
private Set events = new HashSet();
public Set getEvents() {
return events;
}
public void setEvents(Set events) {
this.events = events;
}
}
Before we map this association, think about the other side. Clearly, we could just keep this unidirectional. Or, we could create another collection on the Event
, if we want to be able to navigate it bi-directional, i.e. anEvent.getParticipants()
. This is not necessary, from a functional perspective. You could always execute an explicit query to retrieve the participants for a particular event. This is a design choice left to you, but what is clear from this discussion is the multiplicity of the association: "many" valued on both sides, we call this a
many-to-many
association. Hence, we use Hibernate's many-to-many mapping:
<class name="events.Person" table="PERSON">
<id name="id" column="PERSON_ID">
<generator class="native"/>
</id>
<property name="age"/>
<property name="firstname"/>
<property name="lastname"/>
<set name="events" table="PERSON_EVENT">
<key column="PERSON_ID"/>
<many-to-many column="EVENT_ID" class="events.Event"/>
</set>
</class>
Hibernate supports all kinds of collection mappings, a <set>
being most common. For a many-to-many association (or
n:m
entity relationship), an association table is needed. Each row in this table represents a link between a person and an event. The table name is configured with the table
attribute of the set
element. The identifier column name in the association, for the person's side, is defined with the <key>
element, the column name for the event's side with the column
attribute of the <many-to-many>
. You also have to tell Hibernate the class of the objects in your collection (correct: the class on the other side of the collection of references).
The database schema for this mapping is therefore:
_____________ __________________
| | | | _____________
| EVENTS | | PERSON_EVENT | | |
|_____________| |__________________| | PERSON |
| | | | |_____________|
| *EVENT_ID | <--> | *EVENT_ID | | |
| EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
| TITLE | |__________________| | AGE |
|_____________| | FIRSTNAME |
| LASTNAME |
|_____________|