Share |

Hibernate Collection Mapping

Hibernate supports collection mapping as value type. In Hibernate collection mapping, the collection are mapped into a separate table but are not exposed as entity on the Java side. Hibernate supports following collection interfaces as value type:
  • java.util.Set – java.util.HashSet is used to store value.
  • java.util.SortedSet – java.util.TreeSet is used to store value.
  • java.util.List – java.util.ArrayList is used to store value. Preserves the position with an index column
  • Bag semantics – java.util.ArrayList is used to store valre however the position is not preserved.
  • java.util.Map – java.util.HashMap is used to store value.
  • java.util.SortedMap – java.util.TreeMap is used to store value.

Let’s say we want to store Phones for a Student. There are more than one Phone for a Student. So we will have two tables corresponding to Student and Phone. However we do not want to expose Phone

Table STUDENT
STUDENT_ID ...


Table PHONE
STUDENT_ID NUMBER ...

STUDENT_ID is the foreign key and PHONE table has no primary key. To map the Phone collection as a Set in the Student Entity class
Student class
... @org.hibernate.annotations.CollectionOfElements(targetElement = java.lang.String.class) @JoinTable( name="PHONE",joinColumns = @JoinColumn(name="STUDENT_ID")) @Column(name="PHONE_NO") public Set<String> getPhones() { ...

The lifecycle of Phone is tightly coupled to Student. Also Phone table is not exposed as an entity. If the Set need to be sorted
... @org.hibernate.annotations.CollectionOfElements(targetElement = java.lang.String.class) @JoinTable( name="PHONE",joinColumns = @JoinColumn(name="STUDENT_ID")) @Column(name="PHONE_NO") @org.hibernate.annotations.Sort(type=org.hibernate.annotations.SortType.NATURAL) public Set<String> getPhones() { ...

A comparator can also be used for Sort type.

To map the Phone collection as a list
... @org.hibernate.annotations.CollectionOfElements @JoinTable( name="PHONE",joinColumns = @JoinColumn(name="STUDENT_ID")) @org.hibernate.annotations.IndexColumn(name=“INDEX_POSITION", base =1) @Column(name="PHONE_NO") public List<String> getPhones() { return phones; }

Here the index is mapped to a INDEX_POSITION column in the table and preserves the ordering. If the index is not given, this works like a Bag. Bag is a list but does not preserves the position.

To map Phone as a map where PHONE_NAME will act as key and PHONE_NO as value from the PHONE table. To map it
... @org.hibernate.annotations.CollectionOfElements @JoinTable( name="PHONE",joinColumns = @JoinColumn(name="STUDENT_ID")) @org.hibernate.annotations.MapKey(columns = @Column(name="PHONE_NAME")) @Column(name="PHONE_NO") public Map<String,String> getPhones() { ...

Here the Phone table is mapped directly as a collection. We can also expose Phone as a value object. In this case define Phone as a class
@Embeddable public class PhoneValue { protected Student student; protected String name; protected String phoneNumber; @org.hibernate.annotations.Parent public Student getStudent() { return student; } ...

Also in the above case we maintain a back pointer for Student so that we can navigate from Phone to Student. To define the collection of embedded object in Student class
... protected Collection<PhoneValue> phoneValues = new ArrayList<PhoneValue>(); @org.hibernate.annotations.CollectionOfElements @JoinTable(name = "Student_Phone_Value",joinColumns = @JoinColumn(name="STUDENT_ID")) @CollectionId(columns= @Column(name="STUDENT_PHONE_VALUE_ID"), type=@org.hibernate.annotations.Type(type="long"), generator="sequence") public Collection<PhoneValue> getPhoneValues() { return phoneValues; } ...

Hibernate collection mapping is a way of mapping the collection table as values. The lifecycle of the the collections are tightly bound to the collection of the owning entity.

Back to Hibernate Index
Back To Java Home
Back To Home

Post new comment

Click for Help
BoldItalicUnderlineStrikethroughExternal LinkSmileys
Anti-Bot verification code: Random Image
Post new comment