【问题标题】:JPA-QL query find all entities with LocalDateTime timestamp between LocalDate startDate and LocalDate endDateJPA-QL 查询查找 LocalDateTime 时间戳在 LocalDate startDate 和 LocalDate endDate 之间的所有实体
【发布时间】:2017-11-01 16:58:10
【问题描述】:

我有一个带有 LocalDateTime 字段的 JPA 实体 TimeSlot,名为 startDateTime

@Entity
public class TimeSlot {

    private LocalDateTime startDateTime;
    ...
}

我在 WildFly 10.1 上使用 Hibernate。如何查询startDateendDate之间的startDateTime的所有实体?

private List<TimeSlot> getTimeSlotsByStartDateEndDate(LocalDate startDate, LocalDate endDate) {
    return entityManager.createNamedQuery("TimeSlot.findByStartDateEndDate", TimeSlot.class)
            .setParameter("startDate", startDate)
            .setParameter("endDate", endDate).getResultList());
}

此查询失败,因为时间戳不是日期:

@NamedQueries({
        @NamedQuery(name = "TimeSlot.findByStartDateEndDate",
                query = "select t from TimeSlot t" +
                        // fails because a timestamp is not a date
                        " where t.startDateTime between :startDate and :endDate"),
})

【问题讨论】:

  • 似乎至少有些 DB 不喜欢在 BETWEEN 运算符中混合 DATE 和 DATETIME/TIMESTAMP。您正在传递 LocalDates(startDateendDate),Hibernate 显然将其转换为 DATE,而 t.startDateTime 是一个 TIMESTAMP。我可以想到 2 个解决方案(但目前无法验证):(1)在 Java 中将 LocalDate 转换为 LocalDateTime 或(2)使用 JPA 的 FUNCTION 并将 DATE 转换为数据库中的 TIMESTAMP,使用底层数据库的特定于数据库的功能。我会选择(1)。祝你好运:)
  • 1) 意味着知道一天的第一个和最后一个时间戳是什么。闰秒使这不那么有趣。我会先调查 2)。
  • 而调用的 SQL 是什么?

标签: java hibernate jpa jsr310


【解决方案1】:

您必须将 LocalDateTime 和 LocalDate 转换为 java.sql.Timestamp,然后将您的转换器类添加到 persistent.xml 文件中,然后一切正常。 对于 LocalDateTimeConverter :

import java.time.LocalDateTime;
import java.sql.Timestamp;
 
@Converter(autoApply = true)
public class LocalDateTimeAttributeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
     
    @Override
    public Timestamp convertToDatabaseColumn(LocalDateTime locDateTime) {
        return locDateTime == null ? null : Timestamp.valueOf(locDateTime);
    }
 
    @Override
    public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
        return sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime();
    }
}

对于本地日期时间:

import java.sql.Date;
import java.time.LocalDate;
 
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
     
    @Override
    public Date convertToDatabaseColumn(LocalDate locDate) {
        return locDate == null ? null : Date.valueOf(locDate);
    }
 
    @Override
    public LocalDate convertToEntityAttribute(Date sqlDate) {
        return sqlDate == null ? null : sqlDate.toLocalDate();
    }
}

最后,将你的类添加到 persistent.xml

<class>xxxx.model.Entities</class>
<class>xxxx.converter.LocalDateConverter</class>
<class>xxxx.converter.LocalDateTimeConverter</class>

【讨论】:

    猜你喜欢
    • 2018-04-09
    • 2018-12-19
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2023-03-25
    • 2011-03-08
    • 2018-06-02
    • 1970-01-01
    相关资源
    最近更新 更多