组件属性的意思是,持久化类的属性是一个复合类型的对象,在持久化过程中,它仅仅被当作值类型,而并非引用另一个持久化实体。
@Entiry
@Table(name="person")
public class Person{
...
private Name name;
}
@Embeddable
public class Name{
@Parent
private Person owner;
}
@Embeddable修饰的类将作为持久化类的组件使用。
为了告诉Hibernate这个owner属性不是普通属性,而是包含Name组件的Person实体,可使用Hibernate本身提供的@Parent注解修饰该属性。
另一种方式:
@Entity
@Table(name="person")
public class Person{
@Embedded
@AttributeOverrides({
@AttributeOverride(name="first",column=@Column(name="person_firstname")),
@AttributeOverride(name="last",column=@Column(name="person_lastname"))
})
private Name name;
}
1.组件属性为集合
映射组件内集合属性的注解与映射实体类里集合属性的注解没有任何区别。
当主程序保存了这样的Person对象后,Hibernate依然将Name组件的各属性映射成不同的数据列,再将Name里的Map属性映射到另一个数据表。
2.集合属性的元素为组件
程序不再使用@Column映射保存集合元素(组件类型)的数据列—Hibernate无法使用单独的数据列保存集合元素(组件类型),程序只要使用@Embeddable修饰组件类即可。
对于这种集合元素是组件的情形,Hibernate依然会把组件的各属性映射到不同的数据列,只是这些数据列将保存在集合属性表中。
3.组件作为Map的索引
@Entity
@Table(name="person")
public class Person{
@ElementCollection(targetClass=Integer.class)
@CollectionTable(name="nick_power_inf",joinColumns=@JoinColumn(name="person_id",nullable=false))
@Column(name="nick_power",nullable=false)
@MapKeyClass(Name.class)
private Map<Name,Integer> nickPower = new HashMap<Name,Integer>();
}
上面的持久化类中使用Name对象作为Map的key,所以程序应该重写Name类的equals()和hashCode()两个方法。
在这种映射关系下,Hibernate会将外键列、Nama属性所映射的多列作为联合主键。
4.组件作为复合主键
使用组件作为复合主键,也就是使用组件作为持久化类的标识符,则该组件类必须满足以下要求:
- 有无参构造器
- 必须实现java.io.Serializable接口。
- 建议正确地重写equals()和hashCode()方法,也就是根据组件类的关键属性来区分组件对象。
当使用组件作为复合主键时,Hibernate无法为这种复合主键自动生成主键值,所以程序必须为持久化实例分配这种组件标识符,显示分配。
当持久化类使用组件作为复合主键时,程序需要使用@EmbeddedId来修饰主键,它同样可以结合@AttributeOverrides和@AttributeOverride两个注解。
Hibernate将会把Name组件所映射的多个数据列作为联合主键。
5.多列作为联合主键
Hibernate允许直接将持久化类的多个属性映射成联合主键。则该持久化类必须满足如下条件:
- 有无参数的构造器。
- 实现java.io.Serializable接口。
- 建议根据联合主键列所映射的属性来重写equals()和hashCode()方法。
直接使用多个@Id修饰这些属性即可。