1.2.2. A unidirectional Set-based association
By adding a collection of events to the
Person
class, you can easily navigate to the events for a particular person, without executing an explicit query - by calling Person#getEvents
. Multi-valued associations are represented in Hibernate by one of the Java Collection Framework contracts; here we choose a java.util.Set
because the collection will not contain duplicate elements and the ordering is not relevant to our examples:
public class Person { private Set events = new HashSet(); public Set getEvents() { return events; } public void setEvents(Set events) { this.events = events; } }
Before mapping this association, let us consider the other side. We could just keep this unidirectional or create another collection on the
Event
, if we wanted to be able to navigate it from both directions. This is not necessary, from a functional perspective. You can 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 is called a many-to-many association. Hence, we use Hibernate's many-to-many mapping:
<class name="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="Event"/> </set> </class>
Hibernate supports a broad range of collection mappings, a
set
being most common. For a many-to-many association, or n:m entity relationship, an association table is required. Each row in this table represents a link between a person and an event. The table name is declared using the table
attribute of the set
element. The identifier column name in the association, for the person 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 (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 | |_____________|