powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Java [игнор отключен] [закрыт для гостей] / StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
19 сообщений из 19, страница 1 из 1
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829330
Nixic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!
Переписываю тут с C# на Java сервис небольшой и вот используется Postgres и в нем процедура, которая принимает json на вход.

Я раньше такое не использовал, всегда простые типы передавал, а тут json парсится уже внутри процедуры и данные идут дальше.
Начал гуглить и ничего толком не нашел, кроме как переписать процедуру в постгресе) Но на это вряд ли пойдут, так как C# сервис тоже будет использоваться и придется и в нем переписывать коллегам.
В общем пытаюсь сделать так:
Код: java
1.
2.
3.
StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("ch.dm_get_model_meta");
storedProcedure.registerStoredProcedureParameter("json", JsonObject.class, ParameterMode.IN);
storedProcedure.setParameter( "json", new JSONObject("{\"modelid\" : " + " 1489 }'")); // тут я уже напрямую строку слепил:) 



и получаю на 2-й строке ошибку
java.lang.IllegalArgumentException: Type cannot be null

Ну ладно, думаю, отдам тебе String. И получаю от постгреса отворот-поворот:
Код: powershell
1.
2.
3.
4.
Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Error calling CallableStatement.getMoreResults] with root cause
org.postgresql.util.PSQLException: ERROR: function ch.dm_get_model_meta(character varying) does not exist
  Подсказка: No function matches the given name and argument types. You might need to add explicit type casts.
  Позиция: 15



Что вот с этим всем делать - не знаю :) Может кто подскажет? Спасибо.
Буду, конечно, еще искать варианты.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829336
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829337
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя, это для JDBC, а у вас JPA.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829339
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NixicБуду, конечно, еще искать варианты.

ИМХО, ищите в сторону имплементации своего собственного типа (копать от org.hibernate.usertype.UserType).

Надеюсь, кто-то подскажет способ проще (для Hibernate).
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829352
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Nixic,
Ничего не понял.
В шарпе json в хранимку передается как строка. Так?
И хранимка уже есть в постгри.
Так?
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829354
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchпроще (для Hibernate).хибер вообще не нужен для json.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829356
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Nixicпереписывать коллегам.они зря json начали пихать в базу.
Вы можете написать рядом свою хранимку с параметром строка и внутри вызвать их хранимку с параметром json.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829384
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp,
Ну лично у нас используется, как раз через UserType. Проблем не наблюдается.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829411
Nixic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC SharpВ шарпе json в хранимку передается как строка. Так?
И хранимка уже есть в постгри.
Так?
Код: powershell
1.
2.
3.
create function dm_get_model_meta(req json) returns json
  language sql
as ... 


Не, в хранимку передается как раз тип json, судя по коду, хотя я не очень хорошо разбираюсь в этом коде, как и в C# ))
Затем из json вытаскивается значение, как-то так:
Код: powershell
1.
(req->>'modelId')::int8)


И используется уже другими процедурами.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829413
Nixic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchPetroNotC Sharp,
Ну лично у нас используется, как раз через UserType. Проблем не наблюдается.
Да, спасибо, видимо так и нужно делать.
Я уже использовал UserType для одной сущности, но для чтения, в GET запросе. Правда использовал com.google.gson.JsonObject,
а не org.json.JSONObject, нужно будет почитать про особенности и отличия этих типов в доках, а то я пока просто их использовал особо не задумываясь.
JSONObject отлично подошел, чтобы возвращать из GET запросов многоуровневые json'ы :)
JsonUserType
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.SerializationException;
import org.hibernate.usertype.UserType;
import org.springframework.lang.Nullable;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

public class JsonUserType implements UserType {

    @Override
    public int[] sqlTypes() {
        return new int[]{Types.CHAR};
    }

    @Override
    public Class<JsonObject> returnedClass() {
        return JsonObject.class;
    }

    @Override
    public boolean equals(final Object x, final Object y) {
        if (x == y) {
            return true;
        }
        if (x == null || y == null) {
            return false;
        }
        return x.equals(y);
    }

    @Override
    public int hashCode(final Object x) {
        if (x == null) {
            return 0;
        }

        return x.hashCode();
    }

    @Nullable
    @Override
    public Object nullSafeGet(final ResultSet rs,
                              final String[] names,
                              final SharedSessionContractImplementor session,
                              final Object owner) throws SQLException {
        final String json = rs.getString(names[0]);
        if (json == null) {
            return null;
        }

        final JsonParser jsonParser = new JsonParser();
        return jsonParser.parse(json).getAsJsonObject();
    }

    @Override
    public void nullSafeSet(final PreparedStatement st,
                            final Object value,
                            final int index,
                            final SharedSessionContractImplementor session) throws SQLException {
        if (value == null) {
            st.setNull(index, Types.OTHER);
            return;
        }

        st.setObject(index, value.toString(), Types.OTHER);
    }

    @Nullable
    @Override
    public Object deepCopy(@Nullable final Object value) {
        if (value == null) {
            return null;
        }
        final JsonParser jsonParser = new JsonParser();
        return jsonParser.parse(value.toString()).getAsJsonObject();
    }

    @Override
    public boolean isMutable() {
        return true;
    }

    @Override
    public Serializable disassemble(final Object value) {
        final Object deepCopy = deepCopy(value);

        if (!(deepCopy instanceof Serializable)) {
            throw new SerializationException(
                    String.format("deepCopy of %s is not serializable", value), null);
        }

        return (Serializable) deepCopy;
    }

    @Nullable
    @Override
    public Object assemble(final Serializable cached, final Object owner) {
        return deepCopy(cached);
    }

    @Nullable
    @Override
    public Object replace(final Object original, final Object target, final Object owner) {
        return deepCopy(original);
    }
}



В ентити прописал так:

SomeEntity
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
@Entity
@Data
@NoArgsConstructor
@Table(name = "some_view", schema = "some_schema")
@TypeDefs({@TypeDef(name = "JsonUserType", typeClass = JsonUserType.class)})
public class SomeEntity {

    @Id
    private Long id;
    @Type(type = "JsonUserType")
    private JsonObject src;

}



В итоге получаю json в нормальном его виде для src, что-то типа { "src": {...}} со множеством вложенных элементов, как раз такой как нужно фронту.
А вот с отправкой через POST да еще в процедуру пока не использовал.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829431
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NixicЗатем из json вытаскивается значение, как-то так:я и написал что зря они так сделали. Такой тип не тащат в базу.
UserType я считаю оверхед и ненужное усложнение.
Как и хибернейт. Он для маппинга.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829434
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Nixic,
Почему нельзя добавить хранимку обертку вы не ответили.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829436
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Nixicкак раз такой как нужно фронту.в шарпе и java модель в базе делают без json, xml и так далее. Простыми типами.
А потом уже в аппСервере только для передачи на фронт КОНВЕРТИРУЮТ в json.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829437
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NixicДа, спасибо, видимо так и нужно делать.-1
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829443
Nixic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC SharpNixicкак раз такой как нужно фронту.в шарпе и java модель в базе делают без json, xml и так далее. Простыми типами.
А потом уже в аппСервере только для передачи на фронт КОНВЕРТИРУЮТ в json.
Так и есть частично, но есть такая штука как различные графики джаваскриптовые с кучей полей своих и все их в бд тащить,
как-то не очень хорошо, в силу постоянно меняющегося API javascript проще закинуть туда json, и да, лучше это делать в String.

И так сейчас фронт иногда ловит баги в виду того, что старые сохраненные ранее json в БД имеют/или уже не имеют тех полей, которые требуются джаваскриптовым компонентам.
Частично в БД реализовано так, что на вход идёт именно json, в C# видимо с таким проблем особо нет и какие-то их либы это легко отправляют, я подробнее не изучал.

Еще судя по десяткам процедур, которые уже есть в бд, они работают именно с json типом, своими методами работы с json,
всё это переписывать явно не будут, тем более, что сервис на C# будет дальше работать. Но так как не у всех сервера на винде, то нужен сервис, который будет работать под линукс.

Когда начинал переписывать сервис, то процедуры заранее не изучал, да и оценку времени на эту задачу делал не я, а другой разработчик, который тоже не ожидал, что будет вот так вот.

Кроме того, вся эта махина используется для OLAP, который так же выдвигает некоторые требования к типу данных.

В общем всё сложно)))
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829444
Nixic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC SharpNixic,
Почему нельзя добавить хранимку обертку вы не ответили.
Это я уточню, спасибо. В понедельник уже.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829456
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Nixic,
Да. OLAP это денормализованные данные. Там пофиг что хранить, пусть даже сам блоб.
Тогда свою хранимку со строкой и сказать что в java знать о типе json совсем нет необходимости.
Валидацию json не делаем. Что есть в бд, строкой прочитали и отправили на http клиент.
Аппсервер olap в java в роли импотента REST.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829461
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC SharpUserTypeесли просто читать из хранимки и передать json то это не нужно.
Это нужно, если в базе ОLTP неизветный в java тип его НАДО В КЛАССЫ ИЛИ КОЛЛЕКЦИЮ.
...
Рейтинг: 0 / 0
StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
    #39829828
Nixic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решение оказалось относительно простым, hibernate не мог кастануть ответ от функции в json.
То есть получалось отправить входящий параметр в функцию в формате json через свой UserType.
А вот возвращала функция тип Types.OTHER
И никак нельзя кастануть это в Types.JAVA_OBJECT
В итоге сделали по другому, кастуем объекты в нужные типы на уровне постгреса:
Код: java
1.
2.
3.
       Query q = entityManager.createNativeQuery("select CAST(f.* as text) from ch.dm_get_model_meta(CAST (? as json)) f");
       q.setParameter(1, "{\"modelId\" : " + " 1489 }");
       return q.getResultList(); // здесь можно взять и вернуть строку resultList.get(0).toString() и преобразовать в JsonObject и отдать на клиента



Вопрос закрыт, всем спасибо :)
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / StoredProcedureQuery registerStoredProcedureParameter JSONObject как? )
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]