Найти объекты между датами в HQL - PullRequest
0 голосов
/ 03 июля 2018

Я использую HQL и javax.persistence. В моей базе данных MySQL у меня есть datetime (например, 2018-01-22 18:00:00). Со стороны клиента мне назначают дату без времени (например, 2018-01-20). Я хочу найти все сущности, где дата и время находятся между startDate и endDate.

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.java billingDateTime поле:

@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$000(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, и я передаю startDate из 2018-01-22 и дату окончания 2018-01-23 (или даже 2018-01-22), я бы ожидал получить эта запись.

1 Ответ

0 голосов
/ 03 июля 2018

Предполагая, что ваш 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 включительно с обоих концов.

Если вы не используете один и тот же часовой пояс для всех значений в базе данных, вам, возможно, придется изучить тип столбца billing_date_time, используемый вашей таблицей, чтобы понять, как он обрабатывает информацию о часовом поясе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...