Composition as list of many classes

Full source code is provided in the package: de.laliluna.component.collection1

In this example the component will have a defined order, which is guarantied by adding a position column to the database.

ClassesTables

images/c_component_collection_list_class.jpg

images/c_component_collection_list_table.jpg

A hedgehog which is successful in life has of course many winter addresses.

Annotation mapping. 

import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import org.hibernate.annotations.CollectionOfElements;
import org.hibernate.annotations.IndexColumn;

@Entity
public class Hedgehog {

   @ElementCollection
   @CollectionTable(name = "hedgehog_winter_addresses",
      joinColumns = @JoinColumn(name = "hedgehog_id"))
    @OrderColumn(name = "list_index")
   //@IndexColumn(name = "list_index")
   private List<WinterAddress> addresses = new ArrayList<WinterAddress>();

@ElementCollection defines the component mapping. @CollectionTable is optional. It specifies the name of the table and the foreign key column. _@IndexColumn (Hibernate API) is optional and defines this relation as an indexed relation.

IndexColumn

Hibernate has always offered the @IndexColumn but since JPA 2 there is a JPA alternative as well. @OrderColumn

The WinterAddress should be made embeddable. If you do not make it embeddable, then the class will be serialized and written to a blob field. You can still read and write the objects, but they are not selectable in the database.

import java.io.Serializable;
import javax.persistence.Embeddable;

@Embeddable
public class WinterAddress implements Serializable{
   private String name;

   private String description;

XML mapping. 

<hibernate-mapping package="de.laliluna.component2">
  <class name="Hedgehog" table="thedgehog">
   ....... snip ........
    <list name="addresses" table="twinteraddress">
      <key column="hedgehog_id" not-null="true"></key>
      <list-index column="list_index"></list-index>
      <composite-element class="WinterAddress">
        <property name="name" type="string"></property>
        <property name="description" type="string"></property>
      </composite-element>
    </list>
  </class>
</hibernate-mapping>

Samples of use:

/* create and set components */
Hedgehog hedgehog = new Hedgehog("Peter");
WinterAddress address1 = new WinterAddress("stack of wood",
   "close to the apple tree");
WinterAddress address2 = new WinterAddress("shelter",
   "old shelter of the neighbour");
hedgehog.getAddresses().add(address1);
hedgehog.getAddresses().add(address2);
session.save(hedgehog);

/* select hedhehogs having a address named „first class hotel“*/
List<Hedgehog> list = session.createQuery
   ("from Hedgehog h left join h.addresses a where a.name = ?")
   .setString(0, "first class hotel").list();

IndexColumn and equals implementation

Using a Set required implementation of equals and hashcode. Using an index column this is not necessary. Hibernate uses the index column to identify an element of the collection.

Using a List and omitting the index column will always lead to the inefficient deletes and reinserts when updating an element. Implementing equals does not help with List.