使用组件作为复合主键,也就是使用组件作为持久化类的标识符,则该组件类必须满足以下的要求。
1) 有无参数的构造器。
2) 必须实现java.io.Serializeble接口。
3) 建议正确地重写equals()和hashCode()方法,也就是根据组件类的关键属性来区分组件对象。
程序先定义如下Name组件类作为实体的主键类型。
public class Name implements java.io.Serializable { // 定义first成员变量 private String first; // 定义last成员变量 private String last; // 无参数的构造器 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; } // 重写equals()方法,根据first、last进行判断 public boolean equals(Object obj) { if (this == obj) { return true; } if (obj != null && obj.getClass() == Name.class) { Name target = (Name)obj; return target.getFirst().equals(getFirst()) && target.getLast().equals(getLast()); } return false; } // 重写hashCode()方法,根据first、last计算hashCode值 public int hashCode() { return getFirst().hashCode() * 31 + getLast().hashCode(); } }
下面Person类将键使用一个Name类型的主键。
@Entity @Table(name="person_inf") public class Person { // 以Name组件作为标识属性 @EmbeddedId @AttributeOverrides({ // 指定 @AttributeOverride(name="first", column = @Column(name="person_firstname")), @AttributeOverride(name="last", column = @Column(name="person_lastname")) }) private Name name; private int age; // name的setter和getter方法 public void setName(Name name) { this.name = name; } public Name getName() { return this.name; } // age的setter和getter方法 public void setAge(int age) { this.age = age; } public int getAge() { return this.age; } }
创建并保存Person对象的程序如下。
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(21); // 创建一个Name对象作为Person对象的标识属性值 person.setName(new Name("owen.org" , "Hibernate")); session.save(person); tx.commit(); HibernateUtil.closeSession(); } }
执行的结果如下。