8.1. 依赖对象(Dependent objects)

组件(Component)是一个被包含的对象,在持久化的过程中,它被当作值类型,而并非一个实体的引用。在这篇文档中,组件这一术语指的是面向对象的合成概念(而并不是系统构架层次上的组件的概念)。举个例子, 你对人(Person)这个概念可以像下面这样来建模:

  1. public class Person {
  2. private java.util.Date birthday;
  3. private Name name;
  4. private String key;
  5. public String getKey() {
  6. return key;
  7. }
  8. private void setKey(String key) {
  9. this.key=key;
  10. }
  11. public java.util.Date getBirthday() {
  12. return birthday;
  13. }
  14. public void setBirthday(java.util.Date birthday) {
  15. this.birthday = birthday;
  16. }
  17. public Name getName() {
  18. return name;
  19. }
  20. public void setName(Name name) {
  21. this.name = name;
  22. }
  23. ......
  24. ......
  25. }
  1. public class Name {
  2. char initial;
  3. String first;
  4. String last;
  5. public String getFirst() {
  6. return first;
  7. }
  8. void setFirst(String first) {
  9. this.first = first;
  10. }
  11. public String getLast() {
  12. return last;
  13. }
  14. void setLast(String last) {
  15. this.last = last;
  16. }
  17. public char getInitial() {
  18. return initial;
  19. }
  20. void setInitial(char initial) {
  21. this.initial = initial;
  22. }
  23. }

在持久化的过程中,姓名(Name)可以作为人(Person)的一个组件。需要注意的是:你应该为姓名的持久化属性定义getter和setter方法,但是你不需要实现任何的接口或申明标识符字段。

以下是这个例子的Hibernate映射文件:

  1. <class name="eg.Person" table="person">
  2. <id name="Key" column="pid" type="string">
  3. <generator class="uuid"/>
  4. </id>
  5. <property name="birthday" type="date"/>
  6. <component name="Name" class="eg.Name"> <!-- class attribute optional -->
  7. <property name="initial"/>
  8. <property name="first"/>
  9. <property name="last"/>
  10. </component>
  11. </class>

人员(Person)表中将包括pid, birthday, initial, firstlast等字段。

就像所有的值类型一样, 组件不支持共享引用。 换句话说,两个人可能重名,但是两个Person对象应该包含两个独立的Name对象,只不过这两个Name对象具有“同样”的值。 组件的值可以为空,其定义如下。 每当Hibernate重新加载一个包含组件的对象,如果该组件的所有字段为空,Hibernate将假定整个组件为空。 在大多数情况下,这样假定应该是没有问题的。

组件的属性可以是任意一种Hibernate类型(包括集合, 多对多关联, 以及其它组件等等)。嵌套组件不应该被当作一种特殊的应用(Nested components should not be considered an exotic usage)。 Hibernate倾向于支持细致的(fine-grained)对象模型。

&lt;component&gt; 元素还允许有 &lt;parent&gt;子元素,用来表明component类中的一个属性是指向包含它的实体的引用。

  1. <class name="eg.Person" table="person">
  2. <id name="Key" column="pid" type="string">
  3. <generator class="uuid"/>
  4. </id>
  5. <property name="birthday" type="date">
  6. <component name="Name" class="eg.Name" unique="true">
  7. <parent name="namedPerson"/> <!-- reference back to the Person -->
  8. <property name="initial"/>
  9. <property name="first"/>
  10. <property name="last"/>
  11. </component&gt;
  12. </class>