前例皆使用單一 @Id(generate=GeneratorType.AUTO) 自動生成主鍵。實務上主鍵可為:
Integer, String 等)使用組合主鍵時,必須將生成策略設為 GeneratorType.NONE,由程式指派主鍵值。主鍵類別必須實作 hashCode() 與 equals()。
@DependentObject(access = AccessType.PROPERTY)
public class Name implements Serializable {
private String first, last;
// 建構子、getter/setter 略
public int hashCode() { return (first + last).hashCode(); }
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Name)) return false;
Name n = (Name) o;
return first.equals(n.first) && last.equals(n.last);
}
}
@Entity @Table(name="STUDENT")
public class Student implements Serializable {
private Name name;
private String grade, email;
@Id(generate = GeneratorType.NONE)
@Dependent(
@DependentAttribute(name="first", column=@Column(name="FIRST")),
@DependentAttribute(name="last", column=@Column(name="LAST"))
)
public Name getName() { return name; }
// grade, email 映射略
}
@DependentObject 標記主鍵類別@Dependent + @DependentAttribute 將主鍵類別屬性展開映射為資料表多欄位 (FIRST, LAST)@Remote
public interface StudentDAO {
void create(String first, String last, String grade, String email);
Student find(Name name);
List findByFirstName(String name);
List findByLastName(String name);
List findByEmail(String email);
void merge(Student s);
}
@Stateless
public class StudentDAOBean implements StudentDAO {
@Inject EntityManager manager;
public void create(String first, String last, String grade, String email) {
Student s = new Student();
s.setName(new Name(first, last));
s.setGrade(grade); s.setEmail(email);
manager.create(s);
}
public Student find(Name name) { return manager.find(Student.class, name); }
public List findByFirstName(String n) {
return manager.createQuery("from Student s where s.name.last = :name")
.setParameter("name", n).listResults();
}
// 其他查詢略
public void merge(Student s) { manager.merge(s); }
}
InitialContext ctx = new InitialContext();
StudentDAO dao = (StudentDAO) ctx.lookup(StudentDAO.class.getName());
dao.create("晁", "岳攀", "8", "smallnest@kuaff.com");
dao.create("朱", "立煥", "6", "zhuzhu@kuaff.com");
Name name = new Name("朱", "立煥");
Student s = dao.find(name);
System.out.printf("%s %s的email:%s%n", s.getName().getFirst(), s.getName().getLast(), s.getEmail());
{$JBOSS_HOME}/bin/run.bat -c allhttps://localhost:8080/jmx-console/ 檢視部署狀態@DependentObject 而非 @Entity)hashCode/equals 實作必須穩定、一致,影響集合操作與快取正確性s.name.last 路徑導航存取組合主鍵屬性