La notion de composants est réutilisé dans différents contextes, avec différents objectifs, à travers Hibernate.
Le composant est un objet inclu dans un autre qui est sauvegardé comme une valeur, et non pas comme une entité. Le composant fait référence à la notion (au sens objet) de composition (et non pas de composant au sens d'architecture de composants). Par exemple on pourrait modélisé l'objet personne de cette façon:
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; } }
Maintenant Name
peut-être sauvegardé comme un composant de Person
. Remarquer que Name
définit des methodes d'accès et de modification pour ses propriétés persistantes, mais il n'a pas besoin des interfaces ou
des propriétés d'identification ( par exemple getId() ) qui sont propres aux entités.
Nous serions alors amené à mapper ce composant de cette façon:
<class name="eg.Person" table="person"> <id name="Key" column="pid" type="string"> <generator class="uuid"/> </id> <property name="birthday" type="date"/> <component name="Name" class="eg.Name"> <!-- class attribute optional --> <property name="initial"/> <property name="first"/> <property name="last"/> </component> </class>
La table person aurai les colonnes pid
, birthday
, initial
, first
and last
.
Comme tous les types valeurs, les composants ne supportent pas les références partagés. En d'autres mots, deux instances de person peuvent avoir un même nom, mais ces noms sont indépendants, ils peuvent être identiques si on les compare par valeur mais ils représentent deux objets distincts en mémoire. La notion de nullité pour un composant est ad hoc. Quand il recharge l'objet qui contient le composant, Hibernate supposera que si tous les champs du composants sont nuls alors le composant sera positionné à la valeur null. Ce choix programmatif devrait être satisfaisant dans la plupart des cas.
Les propriétés d'un composant peuvent être de tous les types qu'Hibernate supporte habituellement (collections, many-to-one associations, autres composants, etc). Les composants inclus ne doivent pas être vus comme quelque chose d'exotique. Hibernate a été conçu pour supporter un modèle objet très granulaire.
Le <component>
peut inclure dans la liste de ses propriétés une référence au <parent>
conteneur.
<class name="eg.Person" table="person"> <id name="Key" column="pid" type="string"> <generator class="uuid"/> </id> <property name="birthday" type="date"/> <component name="Name" class="eg.Name" unique="true"> <parent name="namedPerson"/> <!-- reference back to the Person --> <property name="initial"/> <property name="first"/> <property name="last"/> </component> </class>