PostgresQL + Spring JPA:org.postgresql.util.PSQLException:错误:无法将类型 bytea 转换为没有时区的时间戳

Posted

技术标签:

【中文标题】PostgresQL + Spring JPA:org.postgresql.util.PSQLException:错误:无法将类型 bytea 转换为没有时区的时间戳【英文标题】:PostgresSQL + Spring JPA: org.postgresql.util.PSQLException: ERROR: cannot cast type bytea to timestamp without time zone 【发布时间】:2020-11-10 19:31:51 【问题描述】:

有时日期范围可能有空值时如何根据日期范围选择行(选择所有行)

我有一个名为 Project(id, name, certificate_date); 的表id 是 int,name 是 varchar(250),certificate_date 是时间戳

然后插入项目时,仅插入 id 和 name,但certificate_date 为空。稍后用户可以认证项目,然后使用用户认证项目的日期使用certification_date 更新该行。所以在项目表中,我可以有一些带有certification_date为空的行和一些带有日期的行(例如2020-06-18 00:12:07)

现在我有一个带有名称的搜索查询,并且有一个过滤器 startDate 和 endDate 来过滤certificate_date。下面是具有完整签名的存储库查询。

@Query(value = "select distinct p.id, p.name, p.certification_date from project p WHERE (LOWER(p.name) LIKE CONCAT('%',LOWER(:searchKey),'%') and ((cast(:startDate as timestamp) is null or p.CERTIFICATION_DATE >= :startDate) AND (cast(:endDate as timestamp) is null or p.CERTIFICATION_DATE < :endDate ))",  nativeQuery = true)
public List<Object[]> searchProjects(@Param("searchKey") String searchKey, @Param("startDate") Date startDate, @Param("endDate") Date endDate);

因此,当 searchProjects() 使用所有值执行时,它会正确返回结果。但是当我不需要日期过滤器时,即 startDate 和 endDate 为空时,它会失败。 (这里我们对 searchKey 没有任何问题,因为如果 searchKey 为 null 我通过 "" 所以它返回所有值)

例外是

org.postgresql.util.PSQLException: ERROR: cannot cast type bytea to timestamp without time zone

那么我需要做些什么来使 startDate 和 endDate 成为可选的,这样如果这些日期没有通过,就返回所有(无论是认证日期是 null 还是有一些值)行?

我也尝试了 *** 的许多解决方案,但它们对我不起作用。

【问题讨论】:

【参考方案1】:
class Employee 
 int id;
 Date birthDate;


List<Employee> findByBirthDateNotNullAndBirthDateLessThanEqualAndBirthDateGreaterThanEqual(Date startDate,Date endDate)

【讨论】:

嗨@Santosh,感谢您的回复。但是我需要 List 作为返回类型和 @Query() 来编写查询,因为在实际场景中我有 3 个表的复杂 Join。这就是为什么我省略了连接部分,只是发布了我遇到的问题。【参考方案2】:
    JPA 无法区分“null”的值,尤其是 PostgreSQL 中“date、timestamp、timestamptz”类型的映射。 我的解决方法如下:
    @Query(value = "select distinct p.id, p.name, p.certification_date from project p " +
            "where LOWER(p.name) LIKE CONCAT('%',LOWER(:searchKey),'%') " +
            "and (cast(cast(:startDate as text) as timestamp) is null or p.CERTIFICATION_DATE >= :startDate) " +
            "and (cast(cast(:endDate as text) as timestamp) is null or p.CERTIFICATION_DATE < :endDate)",  nativeQuery = true)
    public List<Object[]> searchProjects(@Param("searchKey") String searchKey, @Param("startDate") Date startDate, @Param("endDate") Date endDate);

【讨论】:

以上是关于PostgresQL + Spring JPA:org.postgresql.util.PSQLException:错误:无法将类型 bytea 转换为没有时区的时间戳的主要内容,如果未能解决你的问题,请参考以下文章

通过 Spring Boot JPA + Postgresql + H2 执行间隔

Spring Boot + Spring Data JPA + PostgreSQL

PostgreSQL springboot spring data jpa 集成

Spring JPA 中的 PostgreSQL 数组运算符

Spring JPA 无法连接到 Postgresql

PostgreSQL,Spring Data JPA:整数 null 解释为 bytea