SimpleJdbcCall не преобразовывает ответ в массив. Кидает ClassCastException
java.lang.ClassCastException:
class [Ljava.lang.Object; cannot be cast to class
[Lru.yota.finservices.rs.db.model.MonthAvgServiceData;
([Ljava.lang.Object; is in module java.base of loader 'bootstrap';
[Lru.yota.finservices.rs.db.model.MonthAvgServiceData; is in unnamed module of loader 'app')
текст ошибки такой.
метод вызова хранимой процедуры.
SimpleJdbcCall call = new SimpleJdbcCall(template)
.withCatalogName(CATALOG_NAME)
.withFunctionName("getMonthAVGServiceRegistryData")
.declareParameters(monthAvgServiceData());
SqlParameterSource source = new MapSqlParameterSource()
.addValue("p_date", date, Types.DATE)
.addValue("p_Service_id", serviceId, Types.BIGINT);
List<MonthAvgServiceData> monthAvgServiceData = Arrays.asList(call.executeFunction(MonthAvgServiceData[].class, source)); // тут ошибка.
метод .declareParameters(monthAvgServiceData());
private SqlOutParameter monthAvgServiceData() {
return new SqlOutParameter("return",
OracleTypes.ARRAY,
"T_MONTH_AVG_SERVICE_DATA_LIST",
new SqlReturnStructArray<>(RecursiveBeanPropertyStructArrayMapper.newInstance(MonthAvgServiceData.class))
);
}
из самой хранимой процедуры данные возвращаются в виде Object. скриншот.
но при попытке преобразовать в массив падает с ошибкой.
Ответы (1 шт):
Тут скорее всего тебя подводит неявный синтаксический сахар от Java. Если посмотреть внутрь реализации SimpleJdbcCall#executeFunction, то можно увидеть следующее:
Т.е. первый параметр сам по себе не используется, а нужен как синтаксический сахар. Возможно твой компилятор заменяет
List<MonthAvgServiceData> monthAvgServiceData = Arrays.asList(call.executeFunction(MonthAvgServiceData[].class, source));
на
List<MonthAvgServiceData> monthAvgServiceData = Arrays.asList((MonthAvgServiceData[])call.executeFunction(MonthAvgServiceData[].class, source));
Потому ошибка и падает.
Почему возвращается Object[], а не MonthAvgServiceData[]. Если заглянуть в реализацию SqlReturnStructArray, то можно увидеть такого рода конструкцию
А метод List#toArray() возвращает нетипизованный массив, в отличии от своего собрата позицией ниже.

Наглядно это проблема может быть показана таким падающим тестом:
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
public class GenericTest {
@Test
void test() {
Object[] arr = new Object[]{"bla", "asd"};
List<String> list = Arrays.asList((String[]) executeFunction(String[].class, arr));
}
public <T> T executeFunction(Class<T> returnType, Object bla) {
return (T) bla;
}
}
Результат теста:
Попробуй небольшую хитрость вида:
List tmp = Arrays.asList((Object[])call.executeFunction(Object[].class, source));
List<MonthAvgServiceData> monthAvgServiceData = (List<MonthAvgServiceData>) tmp;



