接續 複合主鍵(一) 的內容。
另一個設計主鍵類別的方式,是讓主鍵類別無需嵌入實體類別,例如,您可以如下設計一個主鍵類別,無需使用任何標注:
- UserPK.java
package onlyfun.caterpillar;
import java.io.Serializable;
public class UserPK implements Serializable {
    private String name;
    private String phone;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final UserPK other = (UserPK) obj;
        if ((this.name == null) ?
            (other.name != null) : !this.name.equals(other.name)) {
            return false;
        }
        if ((this.phone == null) ?
            (other.phone != null) : !this.phone.equals(other.phone)) {
            return false;
        }
        return true;
    }
    @Override
    public int hashCode() {
        int hash = 5;
        hash = 73 * hash + (this.name != null ? this.name.hashCode() : 0);
        hash = 73 * hash + (this.phone != null ? this.phone.hashCode() : 0);
        return hash;
    }
}必須實作Serializable介面,且必須重新定義equals()與hashCode()方法,必須有無參數(預設)建構子。
而在設計User類別時,必須使用@IdClass標注主鍵類別之資訊,而User中有對應於表格欄位的所有資訊,而對應主鍵的屬性,使用@Id標注:
- User.java
package onlyfun.caterpillar;
import java.io.Serializable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
@Entity
@Table(name="T_USER")
@IdClass(onlyfun.caterpillar.UserPK.class)
public class User implements Serializable {
    @Id
    private String name;
    @Id
    private String phone;
    private Long age;
    public Long getAge() {
        return age;
    }
    public void setAge(Long age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
}儲存時的一個例子是:
User user = new User();
user.setName("bush");
user.setPhone("0970123456");
user.setAge(new Long(35));
User user = new User();
user.setUserPK(pk);
user.setAge(new Long(35));
EntityManager entityManager =
JPAUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction etx = entityManager.getTransaction();
etx.begin();
entityManager.persist(user);
etx.commit();
entityManager.close();
只是在語義上,若無特別註解或文件說明,使用User實例時,可能忽略了主鍵欄位所對應的屬性必須全部填寫而發生錯誤。
若要載入User資料,一樣是使用UserPK實例:
UserPK pk = new UserPK();
pk.setName("bush");
pk.setPhone("0970123456");
EntityManager entityManager =
JPAUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction etx = entityManager.getTransaction();
etx.begin();
User user = entityManager.find(User.class, pk);
etx.commit();
entityManager.close();

