Spring Data返回List <biginteger>而不是List <long>

时间:2015-06-23 19:28:16

标签: postgresql hibernate-mapping spring-data-jpa

我在spring-data上实现了DAO:

public interface TestDataRepository extends CrudRepository<DpConfigData, Long> {
@Query(value = "select distinct(oid) from unit", nativeQuery = true)
    List<Long> testMethod();
}

进行单元测试以测试被管理的DAO:

@Test
public void test(){
    List<Long> testData = dpConfigDataEntityDataRepository.testMethod();
    for (Long oid:testData){
        System.out.print(oid);
    }
}

运行测试会产生奇怪的结果 - 运行时的List<Long> testData由BigInteger实例填充,而不是由Long填充。结果我得到 ClassCastException:java.math.BigInteger无法强制转换为java.lang.Long

JPA实现 - Hibernate。 作为DB我使用PostgreSQL,unit.oid字段在DB层上有BigInt类型。 在获取整个单元的情况下它被映射到Long,但是使用自定义查询作为“select distinct ...”时出现了错误并且它被映射到BigInteger。

所以,我的问题是:这种奇怪行为的原因是什么? 如何以优雅的方式解决/解决它?

5 个答案:

答案 0 :(得分:5)

这是Spring数据JPA的一个问题。 如果在DB中数据类型被定义为BigInteger,并且在JPA查询中我们尝试获取Long,那么它将不会给出任何错误,但它在Long数据类型中将值设置为BigInteger。

<强>解决方案:

  1. 使用 BigInteger 作为返回类型

    @Query(value = "select distinct(oid) from unit", nativeQuery = true) List<BigInteger> testMethod();

    然后将变量设置如下。
    Long variable = bigIntegerValue.longValue();

  2. 使用字符串作为返回类型并转换为长

    @Query(value = "select distinct(oid) from unit", nativeQuery = true) List<String> testMethod();

    然后将值设置为

    Long variable = Long.valueOf(stringValue);

  3. 将DB列类型更改为整数/数字。

  4. 实体对象中获取值。

    Long variable = dpConfigData.getOid();

    其中dpConfigData是实体的对象(DpConfigData.class)

答案 1 :(得分:0)

postgresql中的BigInt映射到BigInteger,因为它是未签名的

我认为您最好的选择是在JPA对象中将oid从Long更改为BigInteger

答案 2 :(得分:0)

最后,我通过手动映射&#34; service&#34;解决了这个问题。层。 示例(伪代码):

public interface TestDataRepository extends CrudRepository<DpConfigData, Long> {
        @Query(value = "select distinct(oid) from unit", nativeQuery = true)
            List<Object> testMethod();
        }
}

然后在服务层我做手动映射:

public class TestServiceImpl extends TestService {
    pulic List<Object> testMethod(){
        List<Object> rawList = testDataRepository.testMethod();
        List<Object> resultList = new ArrayList(rawList.size());
        for(Object rw:rawList){
            resultList.add(Long.valueOf(String.valueOf(rw)));
        }
        return resultList;
    }
}

答案 3 :(得分:0)

您可以使用JPQL尝试以下操作:

public interface TestDataRepository extends 
JpaRepository<DpConfigData, Long> {
@Query(value = "select distinct(u.oid) from unit u")
   List<Long> testMethod();
  }

只需确保您的实体对象还应具有与给定属性相同的数据类型Long。

答案 4 :(得分:0)

此问题似乎在2.1.8版中已解决

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.8.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>