2016-01-07 55 views
1

我有以下結構:PlayFramework - 頁排序方式一對多關係的最後一項

public class ConversationModel extends Model { 

    @Id 
    public Long id; 

    @OneToMany(mappedBy="conversation", cascade= CascadeType.ALL) 
    public List<EventModel> events; 

} 

public abstract class EventModel extends Model { 

    @Id 
    public Long id; 
    public Date time; 

} 

現在,當我從會話模型獲取一個網頁,我要訂購他們通過數組事件中的最新條目EventModel。

我想是這樣的:

  return find.where().disjunction() 
       .add(Expr.ilike("name", "%" + filter + "%")) 
       ... 
       .orderBy("events.time desc, " + sortBy + " " + order) 
       .findPagedList(page, pageSize); 

但是,這在某種程度上返回分頁的列表,每個事件ConversationModel的條目。 (例如,如果它有3個事件,則是相同對話的3倍) 如果我在orderBy查詢中省略「events desc」,我會得到所需的結果,但沒有正確排序。

我也嘗試在查詢中設置.setDistinct(true),但返回「無效的SQL語法」。

如何將所有對話分類到最新的事件條目?

感謝您的幫助。

編輯:

我設置一個示例項目,這說明問題:

https://github.com/dominik-ziegler/play-page-sort

在第一次啓動該應用程序打印的談話到控制檯:

[debug] - application - Conversation: First Conversation; ID1 
[debug] - application - Conversation Last Message: Tue Jan 12 23:03:55 CET 2016 
[debug] - application - ---------- 
[debug] - application - ---------- 
[debug] - application - Conversation: Second Conversation; ID2 
[debug] - application - Conversation Last Message: Tue Jan 12 23:03:55 CET 2016 
[debug] - application - ---------- 
[debug] - application - ---------- 
[debug] - application - Conversation: Third Conversation; ID3 
[debug] - application - Conversation Last Message: Tue Jan 12 23:03:55 CET 2016 
[debug] - application - ---------- 

但根據插入日期的順序應該是:

  1. 第二對話
  2. 三對話
  3. 第一次談話

回答

1

在你ConversationModel你可以用@javax.persistence.OrderBy註釋字段,即:

@OneToMany(mappedBy="conversation", cascade= CascadeType.ALL) 
@OrderBy("time DESC") 
public List<EventModel> events; 

它會做你需要什麼 - 按照您的意願對事件進行排序,而無需觸及主排序(因此您可以添加其他排序以進行轉換在查找查詢中查找)。

編輯:達到你需要與
GROUP BY conversation.idORDER BY event.id執行查詢你想要什麼:

MySQL的僞代碼):

SELECT c.id c0, e.id FROM conversation c 
    LEFT OUTER JOIN event e ON c.id = e.conversation_id 
    WHERE lower(c.name) LIKE '%foo%' 
    GROUP BY c.id 
    ORDER BY e.id DESC; 

不幸的是裸搜索韓元不讓你這樣做,但你可以用自己的WHERE構建你的PagedList,增加如下分組:

PagedList<ConversationModel> convsPage = Ebean 
    .createQuery(
     ConversationModel.class, 
     "WHERE lower(name) like :search GROUP BY id" 
    ) 
    .setParameter("search","%"+filter+"%") 
    .order("events.id DESC") 
    .findPagedList(page, pageSize); 
+0

檢查拉請求,也清除在這篇文章下的評論;)如果提交是你需要讓我知道我會改變答案 – biesior

+0

你先生是一個絕對的天才!謝謝! – dominik