在 HQL 中查找日期之间的实体

Find entities between dates in HQL

我正在使用 HQL 和 javax.persistence。在我的 MySQL 数据库中,我有一个日期时间(例如 2018-01-22 18:00:00)。从客户端,我收到了一个没有时间的日期(例如 2018-01-20)。我想找到日期时间在 startDateendDate 之间的所有实体。

public List<BillingRunEntity> getBillingRuns(List<String> accountIds, LocalDate startDate, LocalDate endDate) {
    String query = "SELECT DISTINCT bre " +
               "FROM BillingRunEntity bre " +
               "WHERE bre.accountId in :accountIds " +
               "AND bre.billingDateTime BETWEEN :startDate AND :endDate";

    return entityManager
        .createQuery(query, BillingRunEntity.class)
        .setParameter("accountIds", accountIds)
        .setParameter("startDate", startDate)
        .setParameter("endDate", endDate)
        .getResultList();
}

我的 BillingRunEntity.javabillingDateTime 字段:

@Column(name = "billing_date_time")
private ZonedDateTime billingDateTime;

1) 尝试 运行 此查询会导致以下错误。考虑到我不关心时间,我该如何解决这个问题?

java.lang.IllegalArgumentException: Parameter value [2018-07-03] did not match expected type [java.time.ZonedDateTime (n/a)]
    at org.hibernate.jpa.spi.BaseQueryImpl.validateBinding(BaseQueryImpl.java:874)
    at org.hibernate.jpa.internal.QueryImpl.access[=12=]0(QueryImpl.java:80)
    at org.hibernate.jpa.internal.QueryImpl$ParameterRegistrationImpl.bindValue(QueryImpl.java:248)
    at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:620)
    at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:180)
    at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:49)

2) 这个查询会按我预期的方式工作吗?我不关心这里的时间 - 如果数据库有 2018-01-22 18:00:00,我传递 2018-01-22startDate2018-01-23 的结束日期(甚至 2018-01-22), 我希望能提取该记录。

假设数据库中的 ZonedDateTime 始终以 UTC 格式存储,您可以简单地转换为 LocalDate

ZoneId utc = ZoneId.of("UTC");
ZonedDateTime startTime = startDate.atStartOfDay(utc);
ZonedDateTime endTime = endDate.atStartOfDay(utc).plusDays(1).minusNanos(1);

[...]

    .setParameter("startDate", startTime)
    .setParameter("endDate", endTime)

minusNanos(1) 可能有点矫枉过正,但 BETWEEN 运算符在两端都包含在内。

如果您不对数据库中的所有值使用相同的时区,您可能需要深入研究 table 使用的 billing_date_time 列类型以了解它如何处理时区信息。