【问题标题】:PlayFramework - Page Sort by last Entry of OneToMany RelationshipPlayFramework - 页面按 OneToMany 关系的最后一个条目排序
【发布时间】:2016-01-07 09:17:50
【问题描述】:

我有以下结构:

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. 第一次对话

【问题讨论】:

    标签: playframework ebean playframework-2.4


    【解决方案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 不允许您这样做,但您可以使用自己的 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);
    

    【讨论】:

    • 检查拉取请求,同时清理这篇文章下的 cmets ;) 如果你需要提交,请告诉我,我会改变答案
    • 您先生绝对是个天才!谢谢!
    猜你喜欢
    • 2016-02-23
    • 2011-12-18
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    相关资源
    最近更新 更多