hibernate - 将 H2 数据转换为 PostgreSQL

标签 hibernate postgresql h2

我正在从 H2 数据库过渡到 PostgreSQL。正如我发现的那样——在 H2 上执行 SCRIPT TO 命令时创建的 SQL 转储包含几个不适当的结构:

  • Unicode 数据用函数 STRINGDECODE('unicode-data') 包装
  • 二进制和 Blob 数据被转义为 X'binary-data' - 可能是十六进制格式(用于将图像和文件直接存储在数据库表中

我设法更改导出的 SQL,使其与 Postgres 兼容,如下所示:

  • Unicode数据用E'unicode-data'包裹
  • 二进制和 Blob 数据被转义为 E'\\xbinary-data' - 应该导入到 Postgres 的 'bytea' 列中

数据导入正常通过。

我将 Hibernate 配置为使用 PostgreSQL 方言,其中 Postgres 的默认二进制和 blob 类型更改为“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 数据列有关......

提前致谢!

附加信息:

这是 FILEDATA 的 Postgres 数据库表定义:

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 正确插入到数据库中,您可以正确加载它!

最佳答案

使用 PostgreSQL 的函数 decode() 解决。答案和示例代码可以在上面的问题中找到:)

关于hibernate - 将 H2 数据转换为 PostgreSQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15873848/

相关文章:

java - Spring:如何使用 CrudRepository 默认返回具有实体连接引用的所有对象

Hibernate Validator - 在实体验证失败后设置默认值

sql - 将列从一个表复制到另一个表

node.js - 使用 postgres 和 sequelize-mock 进行单元测试模拟

sql - 在 PostgreSQL 查询中按降序聚合字符串

java - 具有常规数据库操作的多用户 Web 应用程序

java - Hibernate 映射文件的替代位置?

playframework - 使用 h2-browser 访问 Play 项目数据库

mysql - 如何将 jbpm-6.1.0.Final 和 wildfly-8.1.0.Final 的数据库从 h2 更改为 mysql

sql - 如何修复 SQL 语句中的 H2 语法错误?