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

Posted

技术标签:

【中文标题】PostgreSQL,Spring Data JPA:整数 null 解释为 bytea【英文标题】:PostgreSQL, Spring Data JPA: Integer null interpreted as bytea 【发布时间】:2019-05-08 00:00:19 【问题描述】:

在 PostgreSQL 中我有表格

CREATE TABLE public.my_table
(
    id integer NOT NULL,
    ...

我想执行查询:显示给定 id 的行。如果 id 为 null,则显示所有行。

我试过了

public interface MyRepository extends JpaRepository<MyTable, Integer> 

    @Query(value = "SELECT * FROM my_table WHERE (?1 IS NULL OR id = ?1)", nativeQuery = true)
    List<MyTable> findAll(Integer id);

如果id != null,一切都很好。但是如果id == null,我会收到错误提示

org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:261) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
...
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
...
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: integer = bytea
  Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440) ~[postgresql-42.2.5.jar:42.2.5]
...

显然短路评估不起作用,null 被转换为bytea

作为一种解决方法,我已将查询值更改为

SELECT * FROM my_table WHERE (?1 IS NULL OR id = (CAST (CAST(?1 AS character varying) AS integer)))

但这并不好,因为 int 被转换为 string 并再次转换为 int。你有更好的解决方案吗,例如更好的演员表或 sql 查询?

【问题讨论】:

【参考方案1】:

另一种解决方法是从 EntityManager 手动创建查询(示例中为 em)并使用非空值调用 setParameter 一次,然后再次使用实际值。

private static final Integer exampleInt = 1;

List<MyTable> findAll(Integer id) 
    return em.createNativeQuery("SELECT * FROM my_table WHERE (:id IS NULL OR id = :id)", MyTable.class)
            .setParameter("id", exampleInt)
            .setParameter("id", id)
            .resultList();

这样可以确保 Hibernate 在下一次调用它时知道值的类型,即使它是 null。

问题出在 PostgreSQL 服务器上,而不是在 Hibernate 中,但他们拒绝修复它,因为它按预期工作。您在服务器上只有几百种 SQL NULL 类型,并且它们大多相互不兼容,即使它应该是一个单一的特殊值。

【讨论】:

把这个留在这里,PostgreSQL 声称他们正确地实现了 JDBC 规范,并且 Hibernate 将nulls 传递给 JDBC 的方式是错误的,因为它们发送的是“typed null”而不是常量 null。如果这确实是 JDBC 规范所说的(我没有检查过),那么即使它们的技巧对其他数据库正确有效,问题也会出在 Hibernate。

以上是关于PostgreSQL,Spring Data JPA:整数 null 解释为 bytea的主要内容,如果未能解决你的问题,请参考以下文章

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

在Spring Boot Data JPA Rest API中使用PostgreSql时,表未找到错误

将 Spring Data 与 PostgreSQL JsonB 类型属性一起使用

带有spring boot JPA Postgresql的data.sql未加载

如何使每个表中的主键值应从数字一(1)开始 - PostgreSQL,Spring data jpa

spring data jpa在使用PostgreSQL表名大小写的问题解决