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.
Classes | Tables |
---|---|
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.
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();
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.