(一)在实体中可以定义一个嵌入式组件(embedded component), 甚至覆盖该实体中原有的列映射. 组件类必须在类一级定义@Embeddable注解. 在特定的实体的关联属性上使用@Embedded和 @AttributeOverride注解可以覆盖该属性对应的嵌入式对象的列映射:
@Entity public class Person implements Serializable { // Persistent component using defaults Address homeAddress; @Embedded @AttributeOverrides( { @AttributeOverride(name="iso2", column = @Column(name="bornIso2") ), @AttributeOverride(name="name", column = @Column(name="bornCountryName") ) } ) Country bornIn; ... }
@Embeddable
public class Address implements Serializable {
String city;
Country nationality; //no overriding here
}
@Embeddable public class Country implements Serializable { private String iso2; @Column(name="countryName") //通过使用@Column来指定数据库中表中字段的名字
private String name;
public String getIso2() { return iso2; } public void setIso2(String iso2) { this.iso2 = iso2; } public String getName() { return name; } public void setName(String name) { this.name = name; } ... }
在上面的例子中,实体bean Person 有两个组件属性, 分别是homeAddress和bornIn. 我们可以看到homeAddress 属性并没有注解. 但是Hibernate自动检测其对应的Address类中的@Embeddable注解, 并将其看作一个持久化组件.对于Country中已映射的属性, 则使用@Embedded和@AttributeOverride 注解来覆盖原来映射的列名. 正如你所看到的, Address对象中还内嵌了Country对象, 这里和homeAddress一样使用了Hibernate和EJB3自动检测机制. 目前EJB3规范还不支持覆盖多层嵌套(即嵌入式对象中还包括其他嵌入式对象)的列映射. 不过Hibernate通过在表达式中使用"."符号表达式提供了对此特征的支持.
@Embedded @AttributeOverrides( { @AttributeOverride(name="city", column = @Column(name="fld_city") ), @AttributeOverride(name="nationality.iso2", column = @Column(name="nat_Iso2") ), @AttributeOverride(name="nationality.name", column = @Column(name="nat_CountryName") ) //nationality columns in homeAddress are overridden } ) Address homeAddress;