Перенос данных H2 в PostgreSQL

Я делаю переход с базы данных H2 на PostgreSQL. Как я выяснил - дамп SQL, который создается при выполнении команды SCRIPT TO на H2, содержит несколько неуместных конструкций:

  • Данные Unicode обертываются функцией STRINGDECODE('unicode-data')
  • Двоичные данные и данные BLOB-объектов экранируются как X'binary-data' - вероятно, шестнадцатеричный формат (используется для хранения изображений и файлов непосредственно в таблице базы данных).

Мне удалось изменить свой экспортированный SQL, чтобы он был совместим с Postgres, следующим образом:

  • Данные Unicode завернуты в E'unicode-data'
  • Двоичные данные и данные BLOB-объектов экранированы как E'\\xbinary-data' — их следует импортировать в столбец bytea в Postgres.

Импорт данных проходит как надо.

Я настроил Hibernate для использования диалекта PostgreSQL, где по умолчанию двоичный и blob-тип Postgres изменен на «bytea»:

public class PostgreDialectFix extends PostgreSQLDialect {

    /**
     * Creates a new instance.
     */
    public PostgreDialectFix() {
        super();

        registerColumnType(Types.BLOB, "bytea");                    
        registerColumnType(Types.LONGVARBINARY, "bytea");           
    }
}

Я также добавил в свой файл persistense.xml следующее:

<!-- PostgreSQL binary data usage ('false' for oid, 'true' for bytea) -->
<property name="hibernate.jdbc.use_streams_for_binary" value="true"/>

Итак, все компилируется и запускается, но когда я пытаюсь открыть страницу, содержащую изображение, которое должно быть загружено из новой базы данных PostgreSQL, возникает следующая ошибка:

Caused by: org.postgresql.util.PSQLException: Bad value of type long : \xffd8ffe000104a46494600010200000100010000ffdb004300...
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.toLong(AbstractJdbc2ResultSet.java:2971)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getLong(AbstractJdbc2ResultSet.java:2163)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getBlob(AbstractJdbc2ResultSet.java:378)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getBlob(AbstractJdbc2ResultSet.java:366)
at org.jboss.resource.adapter.jdbc.WrappedResultSet.getBlob(WrappedResultSet.java:386)
at org.hibernate.type.BlobType.get(BlobType.java:80)
at org.hibernate.type.BlobType.nullSafeGet(BlobType.java:134)
at org.hibernate.type.AbstractType.hydrate(AbstractType.java:105)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2124)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1404)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1332)
at org.hibernate.loader.Loader.getRow(Loader.java:1230)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:603)
at org.hibernate.loader.Loader.doQuery(Loader.java:724)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadCollectionBatch(Loader.java:2053)
... 99 more

Итак, мой вопрос: что происходит не так в этом переходе? Я думаю, что это связано с импортом данных или настройкой Hibernate для правильного чтения столбцов данных Postgres...

Заранее спасибо!

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ:

Вот определение таблицы базы данных Postgres для FILEDATA:

CREATE TABLE filedata
(
  id bigint NOT NULL,
  version integer,
  created timestamp with time zone,
  createdbymemberid bigint,
  modified timestamp with time zone,
  modifiedbymemberid bigint,
  filedata bytea,
  file_id bigint,
)
WITH (
  OIDS=FALSE
);       

НАКОНЕЦ-ТО НАЙДЕНО РЕШЕНИЕ: чтобы импортировать данные файла из базы данных H2 в базу данных PostgreSQL, вам необходимо использовать функцию декодирования PostgreSQL (filedata-in-hex, 'hex'). Вот пример импорта:

INSERT INTO PUBLIC.FILEDATA(ID, VERSION, CREATED, CREATEDBYMEMBERID, MODIFIED, MODIFIEDBYMEMBERID, FILEDATA, FILE_ID) VALUES
(174849, 0, TIMESTAMP '2013-02-11 14:47:57.743', 174833, NULL, NULL, decode('89504e470d0a1a0a0000000d494844520000007b00000050080600000039ac0a8a00000c1a4944415478daed5d095494d7151e136bb3b659baa5494c62dbc4d85a4dba9ee6a49bd6b4f5246dd29ec6a5ae803126261aad5b5ca24489bb6ca2800a0ac822288280ca22b8a251510165515059040541d661bbbddf9b19986146f9c1f90707df77ce3bc30c33ef9f79dfbbefdefbdebdf7d790c47d038d1c0249b684245b42922d21c99690644b48b22524d912926c0949b684245be2be203bb9289b3cd213e9d3c3c1f49ffd...', 'hex'), 174848);

После этого импорт правильно вставляется в базу данных как bytea, и вы можете правильно загрузить его!


person MykoB    schedule 08.04.2013    source источник
comment
Не могли бы вы найти это значение в сценарии, а затем опубликовать определение таблицы и инструкцию вставки, которая не удалась? Так намного проще увидеть, что не так.   -  person Thomas Mueller    schedule 09.04.2013
comment
Кстати, есть несколько инструментов, которые могут помочь в переносе данных, например, SQuirreL DB Copy Plugin — на самом деле таких инструментов больше.   -  person Thomas Mueller    schedule 09.04.2013
comment
Спасибо Томас! Я обновил сообщение с образцом запрошенной информации. Кстати, я попытался использовать плагин SQuirrel DB Copy, но безуспешно из-за большого объема данных для копирования. Таким образом, единственным препятствием для показа являются эти двоичные столбцы и их чтение..: )   -  person MykoB    schedule 09.04.2013
comment
Вы уверены, что настроили Hibernate на использование вашего специального диалекта?   -  person Andrew Lazarus    schedule 09.04.2013


Ответы (1)


Решено с помощью функции PostgreSQL decode(). Ответ и пример кода можно найти в вопросе выше :)

person MykoB    schedule 26.04.2013