2013-02-20 94 views
0

說我有一個實體獲得一個JPA標準查詢與繼承列表

@Entity 
public class Test { 
    @ManyToMany 
    @JoinTable(..etc..) 
    private List<Subject> subjects; // School subjects this test is associated with 
    .... 

以及實體

@Entity 
public class Exam extends Test { 
    // Inherits subjects from test 
    // Does some things specific to exams 
    ... 

我想寫一個條件查詢(用元模型)的工作,讓我只有Exam s與某個Subject相關聯。我的問題是:我如何編寫這個查詢?

我已經試過如下:

如果我寫

CriteriaBuilder cb = em.getCriteriaBuilder(); // em is the EntityManager 
    CriteriaQuery<Exam> cq = cb.createQuery(Exam.class); 
    Root<Exam> root = cq.from(Exam.class); 

    cq.where(cb.isMember(subject, root.get(Exam_.subjects))); 

    return em.createQuery(cq); 

編譯器不會編譯它,說error: no suitable method found for get(ListAttribute<Test,Subject>)。直覺上,這似乎應該是解決方案,但繼承不夠。如果我在查詢中省略了元模型引用並將其替換爲root.get("subjects"),它也不起作用。

如果我寫

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Exam> cq = cb.createQuery(Exam.class); 
Root<Test> root = cq.from(Test.class); 

cq.where(cb.isMember(subject, root.get(Exam_.subjects))); 

return em.createQuery(cq); 

這感覺不對,但它編譯。但是,在實際執行代碼時,我會看到一個例外情況:IllegalStateException: No explicit selection and an implicit one could not be determined,我認爲這是由於圍繞Root的類型而變化的結果。嘗試root.get(Test_.subjects)會得到相同的結果。

我使用Hibernate作爲我的JPA實現,但我試圖堅持JPA標準查詢。

回答

0

在JPQL(我真的勸你的時候,你並不需要一個動態生成的查詢使用),你會寫這樣的:

select e from Exam e 
inner join e.students student 
where student.id = :studentId 

如果你真的想使用標準的API編寫這個查詢,做同樣的事情:創建一個連接並檢查連接的實體的ID是否與給定的學生ID相同。它應該是這樣的:

Join<Exam, Student> studentJoin = root.join(Exam_.students); 
cq.where(qb.equal(studentJoin.get(Student_.id), student.getId()); 
+0

感謝您的輸入 - 你的代碼的產量從數據庫中0結果應該提供一個極少數的查詢,所以我會盡力嘗試多一點與我之前標記它正確連接。 – DCKing 2013-02-20 23:21:57