Возврат данных Spring <biginteger> вместо списка <long>

У меня есть реализация 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 - спящий режим. В БД я использую PostgreSQL, unit.oid поле имеет тип BigInt на слое DB. Он отображен на Long в случае выборки всего блока, но с настраиваемым запросом как "select different..." что-то пошло не так, и оно сопоставляется с BigInteger.

Итак, мой вопрос: в чем причина такого странного поведения? Как решить/переделать его элегантным способом?

Ответ 1

Наконец, я работал над этой проблемой с помощью ручного сопоставления на слове "service". Пример (псевдокод):

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

затем в Service Layer я выполняю ручное сопоставление:

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

Ответ 2

Это проблема с данными JPA Spring. Если в DB тип данных определяется как BigInteger, а в запросе JPA мы пытаемся извлечь как Long, тогда он не даст никакой ошибки, но установил значение как BigInteger в Long datatype.

Решения:

  1. Использовать BigInteger как возвращаемый тип

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

    затем установите переменную, как показано ниже.
    Long variable = bigIntegerValue.longValue();

  2. Используйте String как возвращаемый тип и конвертируйте в Long

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

    затем установите значение как

    Long variable = Long.valueOf(stringValue);

  3. Измените тип столбца DB на Integer/Number.

  4. Получить значение из объекта сущности.

    Long variable = dpConfigData.getOid();

    где dpConfigData является объектом Entity (DpConfigData.class)

Ответ 3

BigInt в postgresql отображает BigInteger, потому что его неподписанные

Я думаю, что ваш лучший вариант - изменить OID от Long до BigInteger в вашем объекте JPA

Ответ 4

Вы можете попробовать это с помощью JPQL, как показано ниже:

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

Просто убедитесь, что ваш Entity Object также должен иметь тот же тип данных Long для данного атрибута.