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

时间:2018-12-06 10:06:01

标签: postgresql hibernate spring-data-jpa

在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强制转换为字符串并再次强制转换为int。您是否有更好的解决方案,例如更好的演员表或SQL查询?

1 个答案:

答案 0 :(得分:1)

另一种解决方法是从EntityManager(在示例中为em)手动创建查询,并在其上使用非null值调用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类型,尽管它们应该是一个奇异的特殊值,但它们彼此之间大多是不兼容的。