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

acruukt9  于 2023-05-12  发布在  Java
关注(0)|答案(5)|浏览(165)

从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

在真实的情况下,我有多个参数,可以为空,我宁愿不检查他们在java代码,但发送到sql查询。我在stackoverflow上检查了问题,但没有找到一个好的答案,特别是对于spring数据库@query注解。

**PostgreSQL处理空值的正确方法是什么?或者你有任何提示如何修复我的方法?**谢谢!
**更新:**问题似乎与nativeQuery = true有关,当value为false时,null值按预期工作。因此,问题是,即使启用了nativeQuery,是否也可以使其正常工作。

kqlmhetl

kqlmhetl1#

试试这个

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

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

0lvr5msh

0lvr5msh2#

您正在尝试检查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);
agxfikkp

agxfikkp3#

我在一个@Query中遇到了类似的问题,其中一个Long被Postgres解释为一个bytea。我的解决方案是取消@Param的装箱……通过传递一个长值,Postgres正确地将该值解释为bigint

olhwl3o2

olhwl3o24#

我知道这是一个老问题,但你应该能够修复海湾铸造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);
4ngedf3f

4ngedf3f5#

我遇到了和你一样的问题。在我研究了这个问题之后,我在https://github.com/spring-projects/spring-data-jpa/issues/2370上找到了答案。
这个问题将通过使用Spring Data JPA 2.7来解决。您可以在https://github.com/heowc-scratch/hibernate_postgres_HHH-14778/tree/main上找到演示这一点的源代码。
也许会有帮助

相关问题