You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data JPA按日期区间查询Tender实体返回0条记录排查

问题描述

我定义了如下Tender实体:

public class Tender {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(nullable = false, updatable = false)
    private Long id;
    private String source;
    private String sourceRefNumber;
    private String link;
    private String title;
    @Column(columnDefinition="TEXT")
    private String description;
    private String field;
    private String client;
    private String type;
    private Date date;
    private Date deadline;
    @ManyToMany
    private List<Cpv> cpv;
}

并创建了对应的Repository接口:

public interface TenderRepository extends JpaRepository<Tender, Long> {

    List<Tender> findAllByDateGreaterThanEqualAndDateLessThanEqual(Date start, Date end);

    List<Tender> findAllByDateBetween(Date start, Date end);
}

我在Service及ServiceImpl中使用该接口,同时在Resource层编写了如下方法:

@GetMapping("/listforperiod/{start}/{end}")
public ResponseEntity<List<Tender>> getTendersForPeriod(@PathVariable("start")
                                                        @DateTimeFormat(pattern = "yyyy-MM-dd") Date start,
                                                        @PathVariable("end")
                                                        @DateTimeFormat(pattern = "yyyy-MM-dd") Date end) {
    List<Tender> list = tenderService.findAllByDateBetween(start, end);
    return new ResponseEntity<>(list, OK);
}

尝试上述两种查询方法后,均返回0条记录,但数据库中明明存在对应数据,请问问题可能出在哪里?

可能的原因及解决方法
  • 日期时间精度不匹配:java.util.Date包含时分秒信息,你通过@DateTimeFormat解析的日期默认时分秒为00:00:00。如果数据库中date字段的记录带有非0的时分秒(比如2024-05-20 14:30:00),那么查询end为2024-05-20时,实际是查询<= 2024-05-20 00:00:00的记录,自然匹配不到。
    解决办法:

    1. 把end日期调整为end日期+1天-1秒,覆盖当天所有时刻的记录;
    2. 改用LocalDate类型映射数据库日期字段,同时将Repository方法参数和Controller的日期解析改为LocalDate,彻底规避时分秒的干扰。
  • 时区不一致:应用程序和数据库的时区可能不匹配,比如应用用UTC时区,数据库存东八区时间,导致日期解析后偏移,查询范围出错。
    解决办法:

    1. 统一两者时区,比如在配置文件中设置spring.jpa.properties.hibernate.jdbc.time_zone=UTC(根据实际时区调整);
    2. 检查数据库表date字段的时区设置,确保和应用一致。
  • JPA查询边界处理差异:findAllByDateBetween在部分JPA实现中是包含起始日期、排除结束日期的逻辑,如果数据库记录刚好是结束日期的0点,会被排除在外。
    解决办法:改用findAllByDateGreaterThanEqualAndDateLessThanEqual并手动调整结束日期范围,或者开启SQL日志查看生成的查询语句,确认边界条件是否符合预期。

  • SQL生成异常:开启JPA的SQL日志,查看实际执行的SQL语句,确认查询条件和参数是否正确。配置方式如下:

    spring.jpa.show-sql=true
    spring.jpa.properties.hibernate.format_sql=true
    

    通过日志可以直观看到日期参数是否和你传入的一致,是否存在绑定错误。

  • 实体字段映射错误:检查Tender类的date字段是否正确映射到数据库的对应列,比如是否存在字段名和列名不匹配(数据库列是tender_date但实体字段是date且未加@Column指定)。
    解决办法:给date字段添加@Column(name = "你的数据库列名"),确保映射关系正确。

内容的提问来源于stack exchange,提问作者Daniil Peterson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:57:21