组件属性的意思是,持久化类的属性并不是基本数据类型,也不是字符串、日期等标量类型的变量,而是一个复合类型的对象,在持久化过程中,它仅仅被当作值类型,而并非引用另一个持久化实体。组件属性的类型可以是任何自定义类。看下面实体的源代码。
@Entity
@Table(name="person_inf")
public class Person
{
@Id @Column(name="person_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private int age;
// 组件属性name
private Name name;
// id的setter和getter方法
public void setId(Integer id)
{
this.id = id;
}
public Integer getId()
{
return this.id;
}
// age的setter和getter方法
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return this.age;
}
// name的setter和getter方法
public void setName(Name name)
{
this.name = name;
}
public Name getName()
{
return this.name;
}
}
上面的自定义类:Name,不能用@Column注解来修饰,需要在自定义的类Name中用@Embeddable来修饰。如下的程序。
@Embeddable
public class Name
{
// 定义first成员变量
@Column(name="person_firstname")
private String first;
// 定义last成员变量
@Column(name="person_lastname")
private String last;
// 引用拥有该Name的Person对象
@Parent // ①
private Person owner;
// 无参数的构造器
public Name()
{
}
// 初始化全部成员变量的构造器
public Name(String first , String last)
{
this.first = first;
this.last = last;
}
// first的setter和getter方法
public void setFirst(String first)
{
this.first = first;
}
public String getFirst()
{
return this.first;
}
// last的setter和getter方法
public void setLast(String last)
{
this.last = last;
}
public String getLast()
{
return this.last;
}
// owner的setter和getter方法
public void setOwner(Person owner)
{
this.owner = owner;
}
public Person getOwner()
{
return this.owner;
}
}
上面的程序,同样可以用@Column来修饰数据列。除此之外,上面的Name类中包含了一个owner,该owner属性指向包含该Name属性的实体(也就是Person对象)。为了告诉Hibernate这个Hibernate这个owner属性不是普通属性,而是包含Name组件的Person实体,可使用Hibernate本身提供的@Parent注修饰该属性。使用如下的程序执行。
public class PersonManager
{
public static void main(String[] args)
{
PersonManager mgr = new PersonManager();
mgr.createAndStorePerson();
HibernateUtil.sessionFactory.close();
}
private void createAndStorePerson()
{
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
// 创建Person对象
Person person = new Person();
// 为Person对象设置属性
person.setAge(29);
// 设置组件属性
person.setName(new Name("owen.org" , "Hibernate"));
session.save(person);
tx.commit();
HibernateUtil.closeSession();
}
}
如果需要为组件属性所包含的子属性指定列名,则可使用@AttributeOverrides和@AttributeOverride注解,其中,@AttributeOverride中要指定name和column的属性。像上面的Person的实体类也可写成下面的。其结果都是一样的。
@Entity
@Table(name="person_inf")
public class Person
{
@Id @Column(name="person_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private int age;
// 组件属性name
@Embedded
@AttributeOverrides({
@AttributeOverride(name="first", column = @Column(name="person_firstname")),
@AttributeOverride(name="last", column = @Column(name="person_lastname"))
})
private Name name;
// id的setter和getter方法
public void setId(Integer id)
{
this.id = id;
}
public Integer getId()
{
return this.id;
}
// age的setter和getter方法
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return this.age;
}
// name的setter和getter方法
public void setName(Name name)
{
this.name = name;
}
public Name getName()
{
return this.name;
}
}