Tuesday, October 18, 2011

Mapping Collections in Hibernate using List interface

Mapping a List in Hibernate:

Implementing the collections using the List interface, provides the position of each element in the collection. Hence it requires an additional column to maintain the position index in the collections table.

Mapping using Hibernate XML mapping:

Let us go to the package com.demo.collections.List and execute the java class ListExecutor.java.

Things to look into:

* The ORM class TeamLeader.java
* The hibernate xml mapping file com.demo.collection.List.hbm.xml

ORM:

Here the variable teamMembers has been declared using the List interface.

public class TeamLeader {

private long id;

private String leaderName;

List teamMembers = new ArrayList();

// getter and setter methods

}

XML mapping file:

<hibernate-mapping auto-import="false">
<class name="com.demo.collections.List.TeamLeader" table="TEAM_LEADER" lazy="false" >
<id name="id" column="LEADER_ID" type="long">
<generator class="native" />
</id>
<property name="leaderName" column="LEADER_NAME" />
<!-- Declaring the List -->
<list name="teamMembers" table="MEMBERS" lazy="false">
<key column="LEADER_ID" />
<list-index column="ORDER_ID" />
<element type="string" column="MEMBER_NAME" not-null="true" />
</list>
</class>
</hibernate-mapping>

* The xml element <list> defines the list interface and the table "MEMBERS" is to store the collection values.
* The xml element key specifies that the primary key of the table TEAM_LEADER will be the foreign key in the table MEMBERS.
* The xml element element represents the column in the collections table to store the collection values.
* The element <list-index> represents the additional column that will be used to store the position index of the elements in the collections.

Note 1: By default the index of the persistent list starts at zero. But it can be changed to start with 1 as follows. <list-index base="1" .../> If the index numbers in the database are not continuous then null will be added in the place of missing indices.

Note 2: The primary key of this collections table will be the combination of key and list-index pairs.

After executing ListExecutor.java, verify the eclipse console and the HSQL DB manager, by executing simple select queries on the tables TEAM_LEADER and MEMBERS as follows.



Mapping List using Annotations:

Let us go to the package annotation.com.demo.collections.List and execute the java class ListAnnotationExecutor.java

Things to look into:

* The annotated ORM TeamLeader.java

@Entity
@Table(name="TEAM_LEADER")
public class TeamLeader {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="LEADER_ID")
private long id;

@Column(name="LEADER_NAME")
@Fetch(FetchMode.SELECT)
private String leaderName;

@org.hibernate.annotations.CollectionOfElements(
targetElement=java.lang.String.class, fetch=FetchType.EAGER) //targetElement is optional if we use generics in the collections
@JoinTable(name="MEMBERS",joinColumns=@JoinColumn(name="LEADER_ID"))
@org.hibernate.annotations.IndexColumn(name="ORDER_ID")
@Column(name="MEMBER_NAME")
List<String> teamMembers = new ArrayList<String>();

* The hibernate annotation @org.hibernate.annotations.CollectionOfElements indicates that the variable teamMembers is of the type collections.
* The targetElement represents the type of element that collection stores and not required if we use the java Generics.
* The annotation @JoinTable is used to mention the table that is used to store the collection values.
* The annotation @JoinColumn here is equivalent to the xml element <key> as mentioned above.
* The hibernate annotation @org.hibernate.annotations.IndexColumn specifies the index column that will store the position of the elements in the collection.

After executing the ListAnnotationExecutor.java, verify the results in the console and in the HSQL DB manager as mentioned above.