2.4.6.2.5. Collection of element or composite elements
Hibernate Annotations also supports collections of core types (Integer, String, Enums, ...), collections of embeddable objects and even arrays of primitive types. This is known as collection of elements.
A collection of elements has to be annotated as @CollectionOfElements (as a replacement of @OneToMany) To define the collection table, the @JoinTable annotation is used on the association property, joinColumns defines the join columns between the entity primary table and the collection table (inverseJoincolumn is useless and should be left empty). For collection of core types or array of primitive types, you can override the element column definition using a @Column on the association property. You can also override the columns of a collection of embeddable object using @AttributeOverride. To reach the collection element, you need to append "element" to the attribute override name (eg "element" for core types, or "element.serial" for the serial property of an embeddable element). To reach the index/key of a collection, append "key" instead.
@Entity
public class Boy {
private Integer id;
private Set<String> nickNames = new HashSet<String>();
private int[] favoriteNumbers;
private Set<Toy> favoriteToys = new HashSet<Toy>();
private Set<Character> characters = new HashSet<Character>();
@Id @GeneratedValue
public Integer getId() {
return id;
}
@CollectionOfElements public Set<String> getNickNames() {
return nickNames;
}
@CollectionOfElements @JoinTable( table=@Table(name="BoyFavoriteNumbers"),
joinColumns = @JoinColumn(name="BoyId") ) @Column(name="favoriteNumber",
nullable=false)
@IndexColumn(name="nbr_index")
public int[] getFavoriteNumbers() {
return favoriteNumbers;
}
@CollectionOfElements @AttributeOverride( name="element.serial",
column=@Column(name="serial_nbr") )
public Set<Toy> getFavoriteToys() {
return favoriteToys;
}
@CollectionOfElements public Set<Character> getCharacters() {
return characters;
}
...
}
public enum Character {
GENTLE,
NORMAL,
AGGRESSIVE,
ATTENTIVE,
VIOLENT,
CRAFTY
}
@Embeddable
public class Toy {
public String name;
public String serial;
public Boy owner;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSerial() {
return serial;
}
public void setSerial(String serial) {
this.serial = serial;
}
@Parent
public Boy getOwner() {
return owner;
}
public void setOwner(Boy owner) {
this.owner = owner;
}
public boolean equals(Object o) {
if ( this == o ) return true;
if ( o == null || getClass() != o.getClass() ) return false;
final Toy toy = (Toy) o;
if ( !name.equals( toy.name ) ) return false;
if ( !serial.equals( toy.serial ) ) return false;
return true;
}
public int hashCode() {
int result;
result = name.hashCode();
result = 29 * result + serial.hashCode();
return result;
}
}
On a collection of embeddable objects, the embeddable object can have a property annotated with @Parent. This property will then point back to the entity containing the collection.
Previous versions of Hibernate Annotations used the @OneToMany to mark a collection of elements. Due to semantic inconsistencies, we've introduced the annotation @CollectionOfElements. Marking collections of elements the old way still work but is considered deprecated and is going to be unsupported in future releases