Возврат данных 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.
Решения:
-
Использовать BigInteger как возвращаемый тип
@Query(value = "select distinct(oid) from unit", nativeQuery = true) List<BigInteger> testMethod();
затем установите переменную, как показано ниже.
Long variable = bigIntegerValue.longValue();
-
Используйте String как возвращаемый тип и конвертируйте в Long
@Query(value = "select distinct(oid) from unit", nativeQuery = true) List<String> testMethod();
затем установите значение как
Long variable = Long.valueOf(stringValue);
-
Измените тип столбца DB на Integer/Number.
-
Получить значение из объекта сущности.
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 для данного атрибута.