Spring数据存储库将null作为bytea发送到PostgreSQL数据库

时间:2016-04-25 07:37:40

标签: java hibernate postgresql spring-data spring-data-jpa

从MySQL切换到 PostgreSQL 后,我发现我的SQL查询(Spring数据存储库界面中的@Query)不再起作用了。该问题是由 null 值发送为 bytea 引起的,并且我得到以下异常:

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.

使用@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);
}

简单测试:

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

在实际情况中,我有多个参数可以为null,我不希望在java代码中检查它们,而是将它们发送到sql查询。我已经在stackoverflow上检查了一些问题,但没有找到一个很好的答案,特别是对于Spring数据存储库@query注释。

使用PostgreSQL处理空值的正确方法是什么?或者您是否有任何提示如何修复我的方法?谢谢!

更新 问题似乎与nativeQuery = true有关,当值为false时,null值按预期工作。所以问题是,即使启用了nativeQuery,是否可以使其正常运行。

4 个答案:

答案 0 :(得分:1)

尝试一下。

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

它满足类型检查器的要求,并且应具有与原始查询相同的属性。如果CAST发生在恒定值而不是数据库行中的值上,则不会对性能造成重大影响。

答案 1 :(得分:0)

您正在尝试检查Java null是否等于Postgres NULL,我认为这是不必要的。您可以重写为以下内容,并且完全避免向simpleTest函数发送null。

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

答案 2 :(得分:0)

我在@Query中遇到类似的问题,其中Long被Postgres解释为bytea。对我来说解决方案是通过传递一个长值来解包@Param ...,Postgres正确地将该值解释为bigint

答案 3 :(得分:0)

我知道这是一个老问题,但是您应该能够修复强制转换Java值的托架。像这样:

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);