Hibernate Component Mapping

A component is a contained object that is persisted as a value type, not an entity reference.
In hibernate the components are reused in different context and purposes. The component mapping can be done in different ways. They are

  1. Dependent Objects
  2. Collection of dependent objects
  3. Components as Map indices
  4. Components as composite identifiers
  5. Dynamic components
Component Mapping
Component Mapping

 

Dependent Objects

The term “component” means it is an object oriented notion of composition and not to architecture level components. Component is a contained object and it is persisted as a value type. Component is not an entity reference.

Eg: –

public class Person {
private java.util.Date birthday;
private Name name;
private String key;
public String getKey() {
return key;
}
private void setKey(String key) {
this.key=key;
}
public java.util.Date getBirthday() {
return birthday;
}
public void setBirthday(java.util.Date birthday) {
this.birthday = birthday;
}
public Name getName() {
return name;
}
public void setName(Name name) {
this.name = name;
}
......
......
}
public class Name {
char initial;
String first;
String last;
public String getFirst() {
return first;
}
void setFirst(String first) {
this.first = first;
}
public String getLast() {
return last;
}
void setLast(String last) {
this.last = last;
}
public char getInitial() {
return initial;
}
void setInitial(char initial) {
this.initial = initial;
}
}

In the above example Name can be persisted as a component of Person For its persistent properties the component Name defines getter and setter methods. Hibernate mapping of above component is given below.

Eg: – Hibernate mapping

<class table="person">
<id column="pid" type="string">
<generator/>
</id>
<property/>
<component> <!-- class attribute optional -->
<property/>
<property/>
<property/>
</component>
</class>

The <component> element permits a <parent> subelement that map a property of the component class as a reference back to the containing entity.

Eg: –

<class name="eg.Person" table="person">
<id column="pid" type="string">
<generator/>
</id>
<property/>
<component unique="true">
<parent/> <!-- reference back to the Person -->
<property/>
<property/>
<property/>
</component>
</class>

 

Collection of dependent objects

An array of type Name is an example of collection of components. By declaring the component collection we are replacing the <element> tag with a <composit-element> tag.

Eg: –

<set table="some_names" lazy="true">
<key column="id"/>
<composite-element> <!-- class attribute required -->
<property/>
<property/>
<property/>
</composite-element>
</set>

Sometimes composite elements consist of components but not collection. Once our composite element consists of components we are using <nested-composit-element> tag. In this case it act as a collection of components which themselves have components.

A special case of a composite element is a composite element with a nested <many-to-one> element. This assignment allows you to map extra columns of a table many-to-many to the composite element class. The following is an association many-to-many of the Order to the point where the price purchaseDate, and the amount owned by the association:

Eg:-

<class .... >
....
<set table="purchase_items" lazy="true">
<key column="order_id">
<composite-element>
<property name="purchaseDate"/>
<property name="price"/>
<property/>
<many-to-one name="item"/> <!-- class attribute is optional -->
</composite-element>
</set>
</class>

In this method ternary associations are also possible.

Eg:

<classMsoListParagraphCxSpMiddle" style="margin-left:.75in;mso-add-space: auto;line-height:150%">    ....
<set table="purchase_items" lazy="true">
<key column="order_id">
<composite-element>
<many-to-one name="purchaseDetails/>
<many-to-one name="item"/>
</composite-element>
</set>
</class>

Composite elements can seem in queries by using the same syntax as association to other entities.

Components as Map indices

The <composite-map-key> element permits us to map a component class as the key of a Map. It ensure that you override hashCode() and equals() correctly on the component class.

Components as composite identifiers

For the use of a component as an identifier of an entity class, our component class must satisfy the following criteria.

1)      It should implement java.io.Serializable.

2)      It should re-implement equals () and hashCode () consistently with the database’s notion of composite key equality.

The IdentifierGenerator never generate composite keys. Instead of that the application

should assign its own identifier.

Use the <composite-id> tag with nested <key-property> elements, in the place of

usual <id> declaration. For example the OrderLine class has a primary key that

depends upon the (composite) primary key of Order.

Eg: –

<class name="OrderLine">
<composite-id name="id">
<key-property/>
<key-property/>
<key-property name="customerId"/>
</composite-id>
<property/>
<many-to-one name="order" insert="false" update="false">
<column/>
<column name="customerId"/>
</many-to-one>
....
</class>

By using an association to OrderLine mapping is given below.

Eg: –

<many-to-one name="orderLine">
<! -- the "class" attribute is optional, as usual -->
<column name="lineId"/>
<column name="orderId"/>
<column/>
</many-to-one>

Many to many and One to many associations are also possible.

Eg: – Many to many and one to many associations

<set name="undeliveredOrderLines">
<key column name="warehouseId"/>
<many-to-many class="OrderLine">
<column/>
<column name="orderId"/>
<column name="customerId"/>
</many-to-many>
</set>

The collection of OrderLines in Order is given below. The one to many elements declares no columns.

<set name="orderLines" inverse="true">
<key>
<column name="orderId"/>
<column name="customerId"/>
</key>
<one-to-many class="OrderLine"/>
</set>

If OrderLine itself owns a collection, it also has a composite foreign key.

<class>
....  ....
<list name="deliveryAttempts">
<key>   <!-- a collection inherits the composite key type -->
<column/>
<column name="orderId"/>
<column name="customerId"/>
</key>
<list-index column="attemptId" base="1"/>
<composite-element class="DeliveryAttempt">
...
</composite-element>
</set>
</class>

Dynamic components

Dynamic component mapping is also possible in the component mapping.

Eg:-

<dynamic-component name="userAttributes">
<property column="FOO" type="string"/>
<property column="BAR" type="integer"/>
<many-to-one column="BAZ_ID"/>
</dynamic-component>

The <dynamic-component> mapping is identical to <component>. The advantages of the dynamic component mapping are

1)      Ability to show the actual properties of the bean at deployment time just by editing the mapping document.

2)      It helps runtime manipulation of the mapping document by using DOM parser.

3)      We can retrieve and change hibernates configuration time metamodel via the Configuration object.