我有以下结构:
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 - ----------
但根据插入日期,订单应为:
答案 0 :(得分:1)
在ConversationModel
中,您可以使用@javax.persistence.OrderBy
注释字段,即:
@OneToMany(mappedBy="conversation", cascade= CascadeType.ALL)
@OrderBy("time DESC")
public List<EventModel> events;
它将满足您的需求 - 可以根据需要对事件进行排序,而无需触及主要排序(因此您可以在查找查询中为对话添加其他排序)。
修改:要实现您的目标,您需要使用
执行查询
GROUP BY conversation.id
和ORDER 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);