传入spring-data方法,null-value param转换为bytea。
简单的测试用例:
我通过电话号码检索用户的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 over Hibernate。作为RDBMS,我们使用PostgreSQL。
PS:对于解决方法,我可以使用类型转换:CAST(:telNumber as varchar),但我不喜欢这个解决方案。我想禁用将null-params转换为 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));
}
答案 0 :(得分:0)
这与Hibernate无关;这就是数据库的工作方式(以及null
意味着未知)的关系模型。
您应该在查询中使用is [not] null
运算符来检查列(JPQL中的实体属性)是否({1}}。
答案 1 :(得分:0)
尝试一下。
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
类型。