Как преобразовать и сопоставить результат вызова хранимой процедуры с PSQL в Spring Boot?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Как преобразовать и сопоставить результат вызова хранимой процедуры с PSQL в Spring Boot?

Сообщение Anonymous »

Меня смущает тип возвращаемого значения вызова хранимой процедуры. Я сделал пользовательский тип в PSQL:

Код: Выделить всё

CREATE TYPE package_dto AS (
id BIGINT,
name VARCHAR(255),
duration INT,
price NUMERIC,
currency VARCHAR(32)
);
Теперь вот хранимая процедура, которую я хочу вызвать:

Код: Выделить всё

CREATE OR REPLACE PROCEDURE update_package(
p_package_id BIGINT,
p_name VARCHAR(255),
p_duration INT,
p_price NUMERIC,
p_currency VARCHAR(32),
OUT o_package package_dto
)
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE package
SET name     = p_name,
duration = p_duration,
price    = p_price,
currency = p_currency
WHERE id = p_package_id
RETURNING id, name, duration, price, currency
INTO o_package.id, o_package.name, o_package.duration, o_package.price, o_package.currency;
END;
$$;
А вот вызовы процедур в слоях моего репозитория:

Код: Выделить всё

    @Query(
value = "CALL update_package(:package_id, :name, :duration, :price, :currency, null)",
nativeQuery = true
)
Object updateProcedure(
@Param("package_id") Long id,
@Param("name") String name,
@Param("duration") Integer duration,
@Param("price") BigDecimal price,
@Param("currency") String currency
);

Так в чем же проблема? Я не могу найти нужную документацию и советы о том, как получить и отобразить результат процедуры. До сих пор мне больше всего повезло с Object, потому что он дает мне максимально общий результат, но это связано с проблемами, связанными с невозможностью сопоставить его с PackageDto (как POJO, так и запись с точно такими же именами полей). Кроме того, как можно правильно утверждать, что процедура выполнена правильно? Будет ли возврат метода репозитория просто возвращать ноль?
До сих пор я пытался с прямым преобразованием поместить PackageDto, Object[], List, List, но безуспешно, Я всегда получаю исключения, что приведение невозможно. Сначала я попробовал использовать @Procedure, который работал, но ТОЛЬКО для случаев, когда вывод прост, например. Длинный или что-то в этом роде. Всякий раз, когда я пытался вернуть определяемую пользователем структуру, это никогда не получалось, поэтому я решил использовать @Query и вручную написать «CALL имя_процедуры...»

Код: Выделить всё

    @Query(
value = "CALL update_package(:package_id, :name, :duration, :price, :currency, null)",
nativeQuery = true
)
Object updateProcedure(
@Param("package_id") Long id,
@Param("name") String name,
@Param("duration") Integer duration,
@Param("price") BigDecimal price,
@Param("currency") String currency
);
Единственный возможный способ получить данные результата — записать их в виде строки, но это крайне ненадежный метод, поскольку я теряю типы данных и имена полей:

Код: Выделить всё

return PackageAdapter.mapToDTO(
packageRepository.updateProcedure(
request.id(),
request.name(),
request.duration(),
request.price(),
Optional.ofNullable(request.currency())
.orElse(ApplicationConstants.DEFAULT_CURRENCY)
)
);

Код: Выделить всё

public static PackageDto mapToDTO(Object object) {
System.out.println("Object: " + object.toString());
System.out.println(JsonUtils.toJson(object));

try {
String[] data = JsonUtils.getValues(object);
Long id = Long.parseLong(data[0]);
String name = data[1];
Integer duration = Integer.parseInt(data[2]);
BigDecimal price = new BigDecimal(data[3]);
Currency currency = Currency.getInstance(data[4]);

return new PackageDto(id, name, duration, price, currency);
} catch (Exception e) {
throw new CustomProcedureMapperException(e.getMessage());
}
}

Код: Выделить всё

    public static String toJson(Object obj) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(obj);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Из метода toJson я получаю строку содержимого, например: "["10", "FitGym 30", "30", "50,00", "EUR"]", которую затем удаляю '[' и ']', разбить на массив строк, а затем вручную задать поля, что далеко от идеала, как вы, вероятно, согласитесь.
Если бы я мог получить прямой объект PackageDto или было бы неплохо хотя бы карту пар ключ-значение после вызова метода репозитория.

Подробнее здесь: https://stackoverflow.com/questions/788 ... pring-boot
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»