传入spring-data方法的空值参数被转换为bytea。
简单的测试用例:
My DAO 通过电话号码检索用户的方法:
@Query(value = "select * from user_account \n"
+ "where case when :telNumber is null then telephone is null\n"
+ " when :telNumber is not null then telephone = :telNumber end", nativeQuery = true)
List<ProdUser> findUserByTelephoneNumber(@Param("telNumber") String telNumber);
然后单元测试:
@Test
public void testUser(){
ProdUser user = prodUserEntityDataRepository.findUserByTelephoneNumber("345324333").get(0);
Assert.assertNotNull(user);
Assert.assertTrue(user.getTelephone().equals("345324333"));
List<ProdUser> users = prodUserEntityDataRepository.findUserByTelephoneNumber(null); //Exception here
Assert.assertNotNull(users);
Assert.assertTrue(users.size() > 0);
}
在 prodUserEntityDataRepository.findUserByTelephoneNumber(null) 行我得到异常:
Caused by: org.postgresql.util.PSQLException: ERROR: operator does not exist: character varying = bytea
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
SQL 参数日志显示任何空值都具有 bytea 类型,这与 varchar、nummber、smallint 等不可比。
有谁知道如何以好的方式解决这个问题?此问题是否与 https://hibernate.atlassian.net/browse/HHH-9165 中描述的 Hibernate 错误有关? ?
对于 DAO,我们使用 Spring-Data 而不是 Hibernate。作为 RDBMS,我们使用 PostgreSQL。
PS:对于解决方法,我可以使用类型转换:CAST( :telNumber as varchar),但我不喜欢这个解决方案。我想禁用将空参数转换为 bytea。
更新:
我有更简单的例子:
DAO 方法:
@Query(value = "select coalesce(:var1, :var2)", nativeQuery = true)
Long coalesce(@Param("var1") Long var1, @Param("var2") Long var2);
单元测试
@Test
public void coalesce(){
Assert.assertEquals(prodUserEntityDataRepository.coalesce(1l,2l), Long.valueOf(1l));
//Here is exeption - org.postgresql.util.PSQLException: ERROR: COALESCE types bytea and bigint cannot be matched
Assert.assertEquals(prodUserEntityDataRepository.coalesce(null,2l), Long.valueOf(2l));
Assert.assertNull(prodUserEntityDataRepository.coalesce(null,null));
}
最佳答案
试试这个。
SELECT *
FROM user_account
WHERE telephone IS NOT DISTINCT FROM CAST(CAST(:telNumber AS TEXT) AS BIGINT)
之所以有效,是因为 IS DISTINCT FROM
接受 NULL
并且 CAST
规避了 Hibernate/PostgreSQL 中的一个错误,其中 null
参数作为 BYTEA
而不是常规的 NULL
类型传递。
https://stackoverflow.com/questions/31655927/