PlayFramework - 按OneToMany关系的最后一个条目排序页面

时间:2016-01-07 09:17:51

标签: playframework ebean playframework-2.4

我有以下结构:

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;

}

现在,当我从Conversation Model中获取页面时,我想通过数组事件中EventModel的最新条目对它们进行排序。

我尝试过类似的事情:

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

但是这会以某种方式返回每个事件的分页列表中的ConversationModel条目。 (例如,如果有3个事件,则为同一对话的3倍) 如果我省略&#34;事件desc&#34;在orderBy查询中,我得到了所需的结果,但没有正确排序。

我还尝试在查询中设置.setDistinct(true),但是返回&#34;无效的SQL语法&#34;。

如何将所有对话分类为最新的活动条目?

感谢您的帮助。

修改

我已经设置了一个示例项目,它显示了问题:

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 个答案:

答案 0 :(得分: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;

不幸的是,裸Finder不允许您这样做,但您可以使用自己的PagedList构建WHERE并添加分组,如:

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);