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.