0

我有一个使用 SpringBoot 的 Java8 应用程序,它引入了 Hibernate 核心 5.3.10(连接到 PostgreSQL 11)。一个简化的解释:该应用程序正在维护一系列定制UserData记录的更改历史记录,其中包含两LocalDateTimestartDateendDate和一userId列(加上其他列)。

该应用程序的语义是,对 的更改历史由UserData维护start_date并且end_date不包含重复项(分别),并且 的任何行endDate都是用户null的当前活动记录。(因此,用户可能没有当前活动记录。)

检索所有活动行是一件简单的事情,而且效果很好。

但是,无论该行是否处于活动状态,我都需要检索所有用户的最新行。

实现此结果的一种方法SQL是使用如下查询:

select ud1.* from user_data ud1
   where ud1.start_date = (select max(ud2.start_date) from user_data ud2 
                                            where ud2.user_id = ud1.user_id);

我一直在尝试编写一个CriteriaQuery来复制 SQL,但我遇到了该CriteriaBuilder.max方法的数据类型问题。该max方法抱怨它只会接受一个类型Number列。代码如下所示:

final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<UserDate> criteriaQuery = builder.createQuery(UserData.class);

final Root<UserData> ud1 = criteriaQuery.from(UserData.class);

final Subquery<LocalDateTime> maxUserDataStartDate = criteriaQuery.subquery(LocalDateTime.class);
final Root<UserData> ud2 = maxUserDataStartDate.from(UserData.class);
maxUserDataStartDate.select(builder.max(ud2.get("startDate"));
// ...

问题出在最后一行,它抱怨这ud2.get("startDate")不是类型的扩展Number——当然,这是真的。

有人知道如何解决这种情况吗?特别是,有没有人可以分享我所追求的例子?

4

1 回答 1

2

您可以通过start_datedesc 订购并获得前 1

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<UserData> criteriaQuery = builder.createQuery(UserData.class);

Root<UserData> ud = criteriaQuery.from(UserData.class);
criteriaQuery.orderBy(builder.desc(ud.get("startDate")));
entityManager.createQuery(criteriaQuery).getFirstResult();
于 2020-07-16T05:26:32.423 回答