Столбец “a” имеет тип integer[], но выражение имеет тип character varying. Подсказка: вам потребуется переписать или привести выражение к нужному типу.

Вопрос или проблема

Я создал двумерный массив (INT[][]) в Postgres. Значения можно сохранять через Dbeaver, но когда я пытаюсь обновить значение из Kotlin, Quarkus, Hibernate, возникает ошибка.

Вот запрос:

`update a set a="{{0,0},{0,0}}" where id=100 (тип a - INT[][])`
`(Panache Repository) aRepository.update("update aEntity set a="{{0,0},{0,0}}" where id=100")`

Вот полный стек трейс:

 `Caused by: org.postgresql.util.PSQLException: ERROR: column "a" is of type integer[] but expression is of type character varying Hint: You will need to rewrite or cast the expression. Position: 23 at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2733) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2420) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:372) at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:517) at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:434) at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:194) at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:155) at io.agroal.pool.wrapper.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:90) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:194) ... 51 more

Класс конвертера:

class MultiDIntArrayConverter : AttributeConverter<Array<IntArray>, String> {

override fun convertToDatabaseColumn(p0: Array<IntArray>?): String {
    if (p0 == null) {
        return ""
    }
    return p0.contentDeepToString().replace("[", "{").replace("]", "}").replace(" ", "")
}

`Любая помощь будет оценена.`

Невозможно сохранить/изменить значения через Hibernate.

Ответ или решение

Ваша проблема связана с тем, что вы пытаетесь обновить столбец типа integer[][] в PostgreSQL, используя строковое представление массива, что вызывает ошибку, так как PostgreSQL ожидает массив, а не строку.

Решение

  1. Преобразование строки в массив: Вам необходимо использовать правильный синтаксис для установки значений многомерного массива в PostgreSQL. Вместо того чтобы конвертировать массив в строку, вы должны передавать массив напрямую.

  2. Использование ARRAY в SQL: В SQL-запросе вам нужно использовать синтаксис массива, допускающий многомерные массивы. Например, для установки значения многомерного массива в PostgreSQL вы можете использовать следующий синтаксис:

    UPDATE a SET a = '{{0,0},{0,0}}'::int[][] WHERE id = 100;

    Обратите внимание на часть ::int[][], которая указывает на то, что вы преобразуете строку в тип int[][].

  3. Изменение вашего кода: Вам нужно обновить строку в вашем Panache Repository, чтобы она использовала правильный формат. Вместо передачи прямой строки, вы можете создать правильный SQL-запрос:

    aRepository.update("UPDATE aEntity SET a = '{{0,0},{0,0}}'::int[][] WHERE id = 100");

Пример конвертера

Если вы продолжаете использовать ваш конвертер MultiDIntArrayConverter, убедитесь, что вы адаптируете его, чтобы он возвращал массив в правильном формате. Однако в данном контексте он вам может не потребоваться, если вы работаете с прямыми запросами. В вашем случае это может выглядеть так:

class MultiDIntArrayConverter : AttributeConverter<Array<IntArray>, String> {

    override fun convertToDatabaseColumn(p0: Array<IntArray>?): String {
        if (p0 == null || p0.isEmpty()) {
            return "{}" // Возвращаем пустой массив, если нет данных
        }
        return p0.joinToString(prefix = "{", suffix = "}", separator = ",") { 
            it.joinToString(prefix = "{", suffix = "}", separator = ",") 
        }
    }

    override fun convertToEntityAttribute(p0: String?): Array<IntArray> {
        // Обработка преобразования из строки обратно в массив
        // (при необходимости)
        // Этот метод можно доработать для обработки извлеченных данных
        return arrayOf() // Возвращаем пустой массив или действительное преобразование
    }
}

Заключение

С указанными изменениями вы сможете успешно обновлять значения в вашей 2D int массиве в PostgreSQL. Обязательно протестируйте ваш код после внесения изменений, чтобы убедиться, что все работает корректно. Если у вас возникнут дополнительные вопросы или потребуется дальнейшая помощь, не стесняйтесь их задавать.

Оцените материал
Добавить комментарий

Капча загружается...