我有三个实体。客户、流程和文件。
一个客户有很多流程,一个流程有很多文档。
我想按文档的更新日期对客户进行排序。
我的实体如下;
顾客;
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Process> processes = new ArrayList<>();
// getter, setter etc.
}
过程;
@Entity
public class Process {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String type;
@ManyToOne(fetch = FetchType.LAZY)
private Customer customer;
@OneToMany(mappedBy = "process", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Document> documents = new ArrayList<>();
//getter, setter etc.
}
文件;
@Entity
public class Document {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String note;
private LocalDateTime updateDate;
@ManyToOne(fetch = FetchType.LAZY)
private Process process;
}
我试过那种规格;
public static Specification<Customer> orderByDocumentUploadDate() {
return (root, query, criteriaBuilder) -> {
ListJoin<Customer, Process> processJoin = root.join(Customer_.processes);
ListJoin<Process, Document> documentJoin = processJoin.join(Process_.documents);
query.orderBy(criteriaBuilder.desc(documentJoin.get(Document_.updateDate)));
query.distinct(true);
return null;
};
}
它给出了错误;
错误:对于select distinct,order by表达式必须出现在选择列表中
生成sql;
select distinct customer0_.id as id1_0_,
customer0_.name as name2_0_
from customer customer0_
inner join
process processes1_ on customer0_.id = processes1_.customer_id
inner join
document documents2_ on processes1_.id = documents2_.process_id
order by documents2_.update_date desc
limit ?
我也尝试过分组。如下图所示;
public static Specification<Customer> orderByDocumentUploadDate() {
return (root, query, criteriaBuilder) -> {
ListJoin<Customer, Process> processJoin = root.join(Customer_.processes);
ListJoin<Process, Document> documentJoin = processJoin.join(Process_.documents);
query.orderBy(criteriaBuilder.desc(documentJoin.get(Document_.updateDate)));
query.groupBy(root.get(Customer_.id));
return null;
};
}
比它给的错误;
错误:列“documents2\u0.update\u date”必须出现在group by子句中或在聚合函数中使用
并生成sql;
select
customer0_.id as id1_0_,
customer0_.name as name2_0_
from
customer customer0_
inner join
process processes1_
on customer0_.id=processes1_.customer_id
inner join
document documents2_
on processes1_.id=documents2_.process_id
group by
customer0_.id
order by
documents2_.update_date desc limit ?
我可以用那个sql来做;max()在sql中解决了这个问题
select customer.* from customer
inner join process p on customer.id = p.customer_id
inner join document d on p.id = d.process_id
group by customer.id
order by max(d.update_date);
但是我不能通过criteriaapi来模拟它。
我怎样才能解决那个问题?你有什么建议吗?
1条答案
按热度按时间ql3eal8s1#
这是一个概念上的误解。
首先,你必须了解内在是如何与工作者结合的。在这种情况下这部分是可以的[加入
process
带的表格document
表基于document.process_id = process.id
]其次,您需要根据文档的更新日期对客户进行排序。
不幸的是,你用
group by
在这里。GROUP BY
只返回它所在的列grouped by
“在这种情况下,它只会返回customer id
.此外,还可以使用聚合函数,如count()、sum()。。。在分组数据上。
所以,当你试图进入
update_date
,它将通过下面的错误。现在我们怎样才能骑上它:
因此,首先我们需要加入以获取客户id。在获取客户id之后,我们应该根据客户id对数据进行分组,然后使用max()获取每个组的max\u日期(如果需要,则使用minimum)
它将返回一个临时表,如下所示:
客户编号:12020-10-2422021-03-1532020-09-2442020-03-15
使用临时表,您现在可以按日期对customer\u id进行排序