2011-12-01 54 views
1

我有一個小問題。在我的應用程序有兩個實體,看起來像在片段:JPA查詢與計數和組(由多對多關係連接表)

//imports, annotations, named queries 
public class WishList implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @SequenceGenerator(name = "wishes_seq", 
         sequenceName = "wish_list_id_seq", 
         allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "wishes_seq") 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "id") 
    private Integer id; 

    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 80) 
    @Column(name = "book_title") 
    private String bookTitle; 

    @Size(max = 80) 
    @Column(name = "book_cattegory") 
    private String bookCattegory; 


    @ManyToMany(cascade= CascadeType.ALL, fetch= FetchType.EAGER) 
    @JoinTable(name="wl_authors", 
       joinColumns={@JoinColumn(name="wl_id")}, 
       inverseJoinColumns={@JoinColumn(name="author_id")}) 
    private List<Author> authorList; 

    // other methods 

,第二個:

//imports, annotations, named queries  
public class Author implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @SequenceGenerator(name = "authors_seq", 
         sequenceName = "authors_id_seq", 
         allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, 
        generator = "authors_seq") 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "id") 
    private Integer id; 

    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 58) 
    @Column(name = "author_name") 
    private String authorName; 

    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 58) 
    @Column(name = "author_surname") 
    private String authorSurname; 

    @Size(max = 58) 
    @Column(name = "nationality") 
    private String nationality; 

    @Size(max = 64) 
    @Column(name = "birth_place") 
    private String birthPlace; 

    @JoinTable(name = "wl_authors", 
       joinColumns = {@JoinColumn(name = "author_id", 
              referencedColumnName = "id")}, 
       inverseJoinColumns = {@JoinColumn(name = "wl_id", 
               referencedColumnName = "id")}) 
    @ManyToMany(fetch = FetchType.EAGER) 
    private List<WishList> wishListList; 

    // other methods 

正如你所看到的實體,這是我準備代表在數據庫中的兩個表,這在多對多關係中(我使用了連接表)。我想算在願望清單實體中的所有結果,它們具有相同的作者,標題和cattegory和返回所有結果如下:

  1. 計數結果
  2. 書名
  3. 書cattegory
  4. 書的作者

結果應按計數結果排序。 我準備的JPA查詢:

SELECT Count(wl.bookTitle) AS POP, 
     wl.bookTitle, 
     wl.bookCattegory 
FROM WishList wl 
GROUP BY wl.bookTitle, 
     wl.bookCattegory, 
     wl.authorList 
ORDER BY POP DESC 

不滿足我。我無法從WishList中退回此書的作者。當我在'FROM'之前放置wl.authorList時出現EJB異常:

... 
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "t1.id" must appear in the GROUP BY clause or be used in an aggregate function 
... 
Call: SELECT COUNT(t0.book_title), t0.book_title, t0.book_cattegory, t1.id, t1.author_name, t1.author_surname, t1.birth_place, t1.nationality FROM wl_authors t4, wl_authors t3, authors t2, authors t1, wish_list t0 WHERE (((t3.wl_id = t0.id) AND (t1.id = t3.author_id)) AND ((t4.wl_id = t0.id) AND (t2.id = t4.author_id))) GROUP BY t0.book_title, t0.book_cattegory, t2.id, t2.author_name, t2.author_surname, t2.birth_place, t2.nationality ORDER BY COUNT(t0.book_title) DESC 
Query: ReportQuery(referenceClass=WishList sql="SELECT COUNT(t0.book_title), t0.book_title, t0.book_cattegory, t1.id, t1.author_name, t1.author_surname, t1.birth_place, t1.nationality FROM wl_authors t4, wl_authors t3, authors t2, authors t1, wish_list t0 WHERE (((t3.wl_id = t0.id) AND (t1.id = t3.author_id)) AND ((t4.wl_id = t0.id) AND (t2.id = t4.author_id))) GROUP BY t0.book_title, t0.book_cattegory, t2.id, t2.author_name, t2.author_surname, t2.birth_place, t2.nationality ORDER BY COUNT(t0.book_title) DESC") 
Caused by: org.postgresql.util.PSQLException: ERROR: column "t1.id" must appear in the GROUP BY clause or be used in an aggregate function 
... 

有人可以幫助我創建apriopriate查詢嗎?是否可以在單個查詢中執行?

回答

0

我不認爲你可以使用一個JPQL查詢來實現它。也許,如果使用本機查詢,你可能會實現它(不知道,壽)。

考慮分拆的問題分爲兩個部分:

  • 調用查詢返回的統計數據,但沒有作者,
  • 爲每個返回行,獲取作者。

所以先引用這樣的查詢:

SELECT DISTINCT COUNT(wl.bookTitle) AS POP, 
       wl.bookTitle, 
       wl.bookCattegory, 
       MAX(wl.id) 
FROM WishList wl 
GROUP BY wl.bookTitle, wl.bookCattegory, wl.authorList 
ORDER BY POP DESC 

據查詢,每個返回行都會有相同的作者。 MAX(wl.id)僅用於獲取您可以查詢作者列表的這些ID之一。

擁有此id您可以爲每條記錄提取作者並返回這些準備好的數據(流行度,書名,類別,作者)。

它肯定不會在性能類別中獲得最高等級,因爲在一個查詢中執行此操作,但此時我沒有看到其他解決方案。

順便說一句 - 你確定你的模型是好的嗎?每個WishList只有一個書名,類別和作者?不應將圖書數據分成Book實體,每個WishList由多個Books組成?我認爲它應該更容易查詢由相同書籍組成的WishLists

+0

嗨。感謝您的答覆。我將嘗試在兩個單獨的查詢中完成。 (在我的模型中,我有名爲Book的實體 - 但它用於其他目的) – problemgenerator

0

我不認爲你可以通過多對多組,

嘗試,

SELECT Count(wl.bookTitle) AS POP, wl.bookTitle, wl.bookCattegory, a.id FROM WishList wl join wl.authorList a GROUP BY wl.bookTitle, wl.bookCattegory, a.id ORDER BY POP DESC 
0

我知道這是一個有點晚,但確實查詢工作的其他數據庫,如MySQL?

Postgres有一個限制,並在選擇部分列出了所有列的強制性,這正是錯誤所說的內容。

v9.1,這個錯誤應該不會再發生了:

當GROUP BY子句中指定的主鍵允許非GROUP BY查詢目標列表中的列[...] SQL標準允許這種行爲,並且由於主鍵,結果是明確的。