JPA - 使用 LocalDate 或 LocalDateTime 按日期获取

JPA - fetching by date using LocalDate or LocalDateTime

我正在使用 Spring 和 JPA 构建一个基本的酒店管理系统。我有一个名为 Order 的实体,它代表一次预订。它包含签入和签出日期,如 LocalDateTime:

private LocalDateTime checkin;
    
private LocalDateTime checkout;

我有一个链接到 Order 的 JPA 存储库 OrderRepository。所有默认方法(查找、保存等)都可以正常工作。

我在'orders'中有一些测试数据table:

id room_id  checkin (DATETIME)          checkout (DATETIME) 
1     1     2020-06-08 00:00:00.000000  2020-06-09 00:00:00.000000
3     2     2020-06-09 00:00:00.000000  2020-06-19 00:00:00.000000
4     1     2020-06-09 00:00:00.000000  2020-06-19 00:00:00.000000

在我的 OrderRepository 中,我想要一种方法来获取所有匹配特定签入或签出日期的订单。问题是,我无法让它与“=”一起工作。虽然它适用于“<”或“>”。

例如,拥有:

public interface OrderRepository extends JpaRepository<Order, Integer> {
    List<Order> findAllByCheckin(LocalDateTime checkin);
}

然后

LocalDateTime date = LocalDateTime.of(2020, 6, 9, 0, 0);        
List<Order> _orders = orderRepository.findAllByCheckin(date);

应该 return 2 项,但 return 是一个空列表

休眠日志输出:

Hibernate: select [...] from orders order0_ where order0_.checkin=?
o.h.type.descriptor.sql.BasicBinder: binding parameter [1] as [TIMESTAMP] - [2020-06-09T00:00]

当我 运行 手动对数据库执行完全相同的 SQL 时,我得到了正确的结果(2 行):

select * from orders order0_ where order0_.checkin='2020-06-09T00:00'

id room_id  checkin (DATETIME)          checkout (DATETIME)     
3   2       2020-06-09 00:00:00.000000  2020-06-19 00:00:00.000000
4   1       2020-06-09 00:00:00.000000  2020-06-19 00:00:00.000000

我还尝试使用 JPQL 手动定义查询。

@Query(value = "select o from Order o where o.checkin = :checkin")
List<Order> findAllByCheckin(@Param("checkin") LocalDateTime checkin);

Hibernate 日志 - 与上面的相同:

Hibernate: select [...] from orders order0_ where order0_.checkin=?
o.h.type.descriptor.sql.BasicBinder: binding parameter [1] as [TIMESTAMP] - [2020-06-09T00:00]

结果相同 - 空列表 returned.

有趣的是,当我更改查询将“=”替换为“<”或“>”时,它工作正常:

@Query(value = "select o from Order o where o.checkin < :checkin")
List<Order> findAllByCheckin(@Param("checkin") LocalDateTime checkin);

returns 1 个元素,符合预期。

我做错了什么?

我使用:

感谢所有建议。

我得到了答案。 MySQL 将所有条目存储为 UTC 时区,看起来 Hibernate 在查询数据库之前将 LocalDateTime 的值从我的本地时区转换为 UTC。因此,在我的例子中,存储“2020-06-09 00:00:00.000000”的 LocalDateTime 在查询中变成了“2020-06-08 22:00:00.000000”,这解释了为什么 '=' 与那些不匹配记录。

也许有一些配置可以控制它,但看起来这是默认情况下的工作方式。