EJB3.0中关于Jpa的复合主键

    当我们需要使用一个或多个属性变量(表中的一列或多列)联合起来作为主键,我们需要使用复合主键。在EJB3.0中复合主键要求我们编写一个复合主键类( Composite Primary Key Class )。下面是个小例子,在Student中要用sid和name做复合主键。
Student实体类:

 1 import javax.persistence.Column;
 2 import javax.persistence.Entity;
 3 import javax.persistence.Id;
 4 import javax.persistence.IdClass;
 5 
 6 @Entity
 7 @IdClass(StudentPK.class)
 8 public class Student {
 9     
10     private String sid;
11     private String name;
12     private String age;
13 
14     @Id
15     public String getSid() {
16         return sid;
17     }
18     public void setSid(String sid) {
19         this.sid = sid;
20     }
21     
22     @Id
23     public String getName() {
24         return name;
25     }
26     public void setName(String name) {
27         this.name = name;
28     }
29     
30     @Column
31     public String getAge() {
32         return age;
33     }
34     public void setAge(String age) {
35         this.age = age;
36     }
37 
38 }

主键StudentPK类:

 1 import java.io.Serializable;
 2 
 3 public class StudentPK implements Serializable{
 4     
 5     private static final long serialVersionUID = 1L;
 6     
 7     private String sid;
 8     private String name;
 9     
10     public StudentPK(){}
11     public StudentPK(String sid,String name){
12         this.sid = sid;
13         this.name = name;
14     }
15     
16     public String getSid() {
17         return sid;
18     }
19     public void setSid(String sid) {
20         this.sid = sid;
21     }
22     public String getName() {
23         return name;
24     }
25     public void setName(String name) {
26         this.name = name;
27     }
28     
29     @Override
30     public int hashCode() {
31         final int prime = 31;
32         int result = 1;
33         result = prime * result + ((name == null? 0 : name.hashCode());
34         result = prime * result + ((sid == null? 0 : sid.hashCode());
35         return result;
36     }
37     
38     @Override
39     public boolean equals(Object obj) {
40         if (this == obj)
41             return true;
42         if (obj == null)
43             return false;
44         if (getClass() != obj.getClass())
45             return false;
46         final StudentPK other = (StudentPK) obj;
47         if (name == null) {
48             if (other.name != null)
49                 return false;
50         } else if (!name.equals(other.name))
51             return false;
52         if (sid == null) {
53             if (other.sid != null)
54                 return false;
55         } else if (!sid.equals(other.sid))
56             return false;
57         return true;
58     }
59     
60 }

主键类必需满足下列条件:
(1)必需被序列化
(2)必需有一个公共的无参构造方法
(3)必需实现equals()和hashCode()方法

当你查询Student实体时必须使用主键类才能识别实体如:

    StudentPK pk = new StudentPK("bj1001","jakin");
    Student student 
= entityManager.find(Student.class, pk);

在测试本例时笔者犯了两个低级的错误,一是测试环境的数据库不是项目运行的数据库,二是实体类中的属性命名用了关键字,请引以为戒。

posted @ 2007-12-04 09:29  Jakin.zhou  阅读(177)  评论(0编辑  收藏  举报