从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,是否可以使其正常运行。
答案 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);