【问题标题】:Spring-data/Hibernate does not work with null-values properlySpring-data/Hibernate 不能正确处理空值
【发布时间】:2015-10-17 19:20:36
【问题描述】:

传入spring-data方法的null-value参数转换为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 参数日志显示任何 null 值的类型为 bytea,与 varchar、nummber、smallint 等不可比。

有人知道如何以好的方式解决这个问题吗?此问题是否与 https://hibernate.atlassian.net/browse/HHH-9165 中描述的 Hibernate 错误有关?

对于 DAO,我们使用 Spring-Data over Hibernate。我们使用 PostgreSQL 作为 RDBMS。

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

【问题讨论】:

    标签: hibernate spring-data


    【解决方案1】:

    试试这个。

    SELECT *
    FROM user_account
    WHERE telephone IS NOT DISTINCT FROM CAST(CAST(:telNumber AS TEXT) AS BIGINT)
    

    之所以有效,是因为IS DISTINCT FROM 接受NULLs 并且CASTs 规避了Hibernate/PostgreSQL 中的一个错误,其中null 参数作为BYTEA 而不是常规的NULL 类型传递。

    【讨论】:

      猜你喜欢
      • 2021-01-08
      • 1970-01-01
      • 1970-01-01
      • 2016-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 2017-02-27
      相关资源
      最近更新 更多