Java JPA条件:按子字段排序时出现错误

Java JPA条件:按子字段排序时出现错误,java,spring,jpa,spring-data-jpa,jpa-criteria,Java,Spring,Jpa,Spring Data Jpa,Jpa Criteria,我有3个实体客户、流程和文档 客户有很多流程,流程有很多文档 我想按文档的updateDate对客户进行排序 我的实体如下所示 顾客- @Entity public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(mappedBy = "custo

我有3个实体客户流程文档

客户有很多流程,流程有很多文档

我想按文档的
updateDate
对客户进行排序

我的实体如下所示

顾客-

@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.

}
我试过以下规格-

  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;
        };
    }
我也尝试过分组,如下所示-

    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;
    };
}
我可以通过下面的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);
但使用
标准
API,我不能做同样的事情


你有什么建议吗?

这是概念上的误解

  • 首先,您必须了解内部联接是如何工作的。在这种情况下,这一部分还可以:[基于
    document.process\u id=process.id
    ]将
    process
    表与
    document
    表连接起来]

  • 其次,您需要根据文档的更新日期对客户进行排序

不幸的是,您在此处使用了
分组方式<代码>分组依据
仅返回其分组依据为的列。在这种情况下,它将只返回
customer\u id

您可以对分组数据使用聚合函数,如
count()
sum()

当您试图访问更新日期时,它将抛出以下错误:

ERROR: column "documents2_.update_date" must appear in the GROUP BY clause or be used in an aggregate function

现在,我们怎样才能摆脱这个呢

  • 因此,首先我们需要执行
    join
    来获取客户id。获取客户id后,我们应该根据客户id对数据进行分组,然后使用max()来获取每个组的max_日期(如果需要,则使用minimum)
选择
客户识别码,
max(日期)作为max_日期
从…起
文件
在process.id=document.process\u id上加入流程
按客户id分组
它将返回一个临时表,如下所示:

客户识别码 最长日期 1. 2020-10-24 2. 2021-03-15 3. 2020-09-24 4. 2020-03-15
这是一种概念上的误解

  • 首先,您必须了解内部联接是如何工作的。在这种情况下,这一部分还可以:[基于
    document.process\u id=process.id
    ]将
    process
    表与
    document
    表连接起来]

  • 其次,您需要根据文档的更新日期对客户进行排序

不幸的是,您在此处使用了
分组方式<代码>分组依据
仅返回其分组依据为的列。在这种情况下,它将只返回
customer\u id

您可以对分组数据使用聚合函数,如
count()
sum()

当您试图访问更新日期时,它将抛出以下错误:

ERROR: column "documents2_.update_date" must appear in the GROUP BY clause or be used in an aggregate function

现在,我们怎样才能摆脱这个呢

  • 因此,首先我们需要执行
    join
    来获取客户id。获取客户id后,我们应该根据客户id对数据进行分组,然后使用max()来获取每个组的max_日期(如果需要,则使用minimum)
选择
客户识别码,
max(日期)作为max_日期
从…起
文件
在process.id=document.process\u id上加入流程
按客户id分组
它将返回一个临时表,如下所示:

客户识别码 最长日期 1. 2020-10-24 2. 2021-03-15 3. 2020-09-24 4. 2020-03-15
    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 ?
    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);
ERROR: column "documents2_.update_date" must appear in the GROUP BY clause or be used in an aggregate function