Spring data repository sends null as bytea to PostgreSQL database

守給你的承諾、 提交于 2021-01-02 05:11:25

问题


After switching from MySQL to PostgreSQL I found out that my SQL query (@Query in spring data repository interface) does not work anymore. The issue is caused by null value being sent as bytea and I'm getting following exception:

Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: bigint = bytea
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.

Repository with @Query:

public interface WineRepository extends PagingAndSortingRepository<Wine, Long> {
    @Query(value = "SELECT * FROM WINE w WHERE (?1 IS NULL OR w.id = ?1)", nativeQuery = true)
    Wine simpleTest(Long id);
}

Simple test:

LOGGER.warn("test1: {}", wineRepository.simpleTest(1L));    //ok
LOGGER.warn("test2: {}", wineRepository.simpleTest(null));  //PSQLException

In the real case I have multiple parameters which can be null and I would prefer not checking them in java code but sending them to sql query. I have checked questions here on stackoverflow but found none with a good answer especially for spring data repository @query annotation.

What is a correct way of handling null values with PostgreSQL? Or do you have any hints how to fix my approach? Thanks!

Update: Issue seems to be related to nativeQuery = true, when value is false, null values work as expected. So the question is whether it is possible to make it function even with nativeQuery enabled.


回答1:


Try this.

SELECT *
FROM WINE w
WHERE ?1 IS NULL OR w.id = CAST(CAST(?1 AS TEXT) AS BIGINT)

It satisfies the type checker and should have the same properties as the original query. CAST is not a big performance hit if it happens on a constant value rather than a value from a database row.




回答2:


You are trying to check whether a Java null is equal to Postgres NULL which I think is not necessary. You can rewrite as following and avoid sending null to the simpleTest function at all.

@Query(value = "SELECT * FROM WINE w WHERE (w.id IS NULL OR w.id = ?1)", nativeQuery = true)
Wine simpleTest(Long id);



回答3:


I had a similar issue in an @Query where a Long was being interpreted by Postgres as a bytea. The solution for me was to unbox the @Param...by passing a long value, Postgres correctly interpreted the value as a bigint




回答4:


I know it is an old issue, but you should be able to fix that bay casting the java value. Something like:

public interface WineRepository extends PagingAndSortingRepository<Wine, Long> {
@Query(value = "SELECT * FROM WINE w WHERE (?1\\:\\:bigint IS NULL OR w.id = ?1\\:\\:bigint)", nativeQuery = true)
Wine simpleTest(Long id);


来源:https://stackoverflow.com/questions/36834537/spring-data-repository-sends-null-as-bytea-to-postgresql-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!