【问题标题】:Query with wrong result JPA Spring Boot查询错误结果 JPA Spring Boot
【发布时间】:2020-08-13 12:57:30
【问题描述】:

我有一个问题,数据库中的@Query 没有让我得到正确的结果。

在 WorkBench 中使用此查询:SELECT * FROM Table WHERE FECHA_INICIO >= '2020-02-01' AND FECHA_FIN <= '2020-02-28',总共返回 18 个结果。

但是使用我的 JAVA 代码,它只显示 6 条记录,它们是在 FECHA_INICIO 列中具有 2020-02-01 和在 FECHA_FIN 列中它们具有值 2020-02-28 的记录。任何这些列中的日期不对应于该月的最后一天或第一天的记录,不显示它们。这就是问题所在。

这是我来自存储库的 JAVA 代码:

public interface TableRepository extends CrudRepository<Table, String> {

    @Query(value = "SELECT * FROM Table WHERE FECHA_INICIO >= :fechaInicio AND FECHA_FIN <= :fechaFin", nativeQuery = true)
    List<Table> findAllBetweenDates(@Param("fechaInicio") Date fechaInicio, @Param("fechaFin") Date fechaFin);
}

我试图查看代码正在执行什么查询,但在日志中它只显示以下内容:

org.hibernate.SQL.logStatement - SELECT * FROM TABLE WHERE FECHA_INICIO >= ? AND FECHA_FIN <= ?

数据库中的两列都是日期类型。添加此代码,如果它适用于我在 PostgreSQL 中的数据库副本中,但在 MySQL 中它只显示 6 条记录而不是 18 条记录。知道会发生什么吗?

编辑:

这是我的实体类:

@Entity
@Table(name = "Table")
public class Table{

    @Id
    @Column(name = "ID", length = 20)
    @NotNull
    private String id;

    @Column(name = "FECHA_INICIO")
    @Temporal(TemporalType.DATE)
    @NotNull
    private Date fechaInicio;

    @Column(name = "FECHA_FIN")
    @Temporal(TemporalType.DATE)
    @NotNull
    private Date fechaFin;

    @Column(name = "DESCRIPTION", length = 20)
    @NotNull
    private String descripcion;
}

【问题讨论】:

  • 存储库中的日期是 java.util.Date 还是 java.sql.Date?另外,您的实体中用于日期的类型是什么?
  • 在我的实体和存储库中是 java.util.Date @RitikaGoel
  • 您能否也分享一下您的实体的结构?
  • 当然@RitikaGoel

标签: mysql spring-boot jpa


【解决方案1】:

据我目前所知,您在实体和存储库中使用java.util.date。请确保您已使用 @Temporal(TemporalType.Date) 注释您实体中的日期字段。

另外,我假设您的 java 版本是 8 或更高版本。如果是这种情况,值得一试java.time.LocalDate。 :)

希望这会有所帮助!

编辑:我今天尝试使用本地设置。虽然我无法复制您的具体问题,但是当我在调试模式下运行代码时,我有一些观察 -

  1. MySQL 的连接 URL 需要时区信息 serverTimezone=UTC。当我没有提供此信息时,它在服务器启动时给了我异常。

  2. 在控制器中使用java.util.Date 时,请求会被解析为时区。因此,对于下面显示的控制器,如果我使用 startDate=2019-01-01 它会转换为 2019 年 1 月 1 日 05:30IST,即它有我的本地时区信息。

    @GettMapping(value = "/test") public List<Test> getResult( @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate, @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) { List<Test> result = testService.getResult(startDate, endDate); return result; }

根据以上观察,我觉得问题可能是因为选择了时区。

此后,我在 Controller、Service、Entity 和 Repository 中将 java.util.Date 更改为 java.time.LocalDate。另外,我从我的实体中删除了@Temporal(TemporalType.Date)。这次在调试中只选择了日期。

**您能否尝试在您的代码中使用java.time.LocalDate 并分享结果。另外,请按照我在评论部分中提到的那样对您的实体进行更改! **

附注- 这可能无法完全解决您的问题,但肯定有助于进一步调试。

【讨论】:

  • 查看实体 ot aeems 您已正确完成所有操作。你能告诉我这些列的数据库数据类型吗?明天我会做一个本地设置,并尝试在我最后重现这个!
  • 在数据库中,列类型是日期
  • 嘿,创建实体时需要注意的几件事 - 它应该为 REST API 实现 Serializable 接口,应该有所有参数并且没有参数构造函数,并且应该存在 getter 和 setter。
  • 我已经实现了,只是因为它们是显而易见的东西(对我来说)我没有放它们
  • 其实我是这么想的! :) 对不起,如果我的评论听起来不同!
【解决方案2】:

很可能您正在比较日期和时间,并且某些行正在被过滤。

例子:

2020-04-23 15:00

2020-04-23 01:00

在执行查询之前,您可以使用以下函数来格式化您的日期(startDate 和 endDate)

private Date getFormattedFromDateTime(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    return cal.getTime();
}

就像@Ritika 所说:请尝试使用 java.time.* 它比 java.util.* 好得多

【讨论】:

  • 这对我不起作用。我不知道原因,但如果不是通过日期 2020-02-01 和 2020-02-28,我通过日期 2020-01-31 和 2020-03-01 如果它取出我需要的所有记录.就好像查询没有在 中使用 =
  • 也许问题不在于 this 查询,而在于您插入记录的那一刻。您应该检查要保存的日期对象。我确定这是一个时区问题。此外,如果您使用 serverTimeZone=UTC,请检查 url 连接,您可以使用此值(将其更改为实际时区)并重试。我希望这对你有用!
猜你喜欢
  • 1970-01-01
  • 2018-10-02
  • 2022-12-11
  • 2021-10-13
  • 2018-02-23
  • 2022-10-12
  • 2021-09-15
  • 2022-01-24
  • 1970-01-01
相关资源
最近更新 更多