Прехвърляне на 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 функция decode(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, но не успях поради голямото количество данни за копиране.. Така че единственият спирач на шоуто са тези двоични колони и тяхното четене.. : )   -  person MykoB    schedule 09.04.2013
comment
Сигурни ли сте, че сте конфигурирали Hibernate да използва вашия специален диалект?   -  person Andrew Lazarus    schedule 09.04.2013


Отговори (1)


Разрешено с помощта на функцията decode() на PostgreSQL. Отговорът и примерният код могат да бъдат намерени във въпроса по-горе :)

person MykoB    schedule 26.04.2013