Hibernate 6、Postgres 和 bytea

BAM*_*con 6 java postgresql hibernate

随着Hibernate 6的发布,我再次绞尽脑汁试图弄清楚如何让 Hibernate 将@Lob转换为PostGres数据库的bytea。我还需要可以使用 H2(或任何内存数据库)测试代码。

我正在使用 Postgres 10+ (v13),因此可以满足该要求。

这是我之前使用的,这很棘手,因为我还需要它与 H2 一起工作。(PostGres 方言仅在生产中加载,不在测试中加载。)

遗憾的是,让 bytea 工作“超出了 Hibernate 6 用户指南的范围”。见 2.2.47。 https://docs.jboss.org/hibernate/orm/6.0/userguide/html_single/Hibernate_User_Guide.html

迁移指南似乎也没有提及这个话题。 https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc

SQLDialect 系列的整个 API 已被重写,所以我回到了方 1。

public class CustomPostgresSQL10Dialect extends PostgreSQL10Dialect{

  public CustomPostgresSQL10Dialect() {
    super();
    registerColumnType(Types.BLOB, "bytea");
  }

  @Override
  public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
    if (sqlTypeDescriptor.getSqlType() == java.sql.Types.BLOB) {
      return BinaryTypeDescriptor.INSTANCE;
    }

    return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
  }
}
Run Code Online (Sandbox Code Playgroud)

Gav*_*ing 6

很难确定,因为您还没有告诉我们您尝试使用注释映射的字段的Java@Lob类型是什么,但是天哪,就这一次我将尝试读懂您的想法,并推测你写的是这样的:

@Lob 
byte[] binaryData;
Run Code Online (Sandbox Code Playgroud)

现在,Postgres JDBC 驱动程序不支持使用 LOB API 来读/写bytea列,而 Hibernate 知道这一点,因此它执行下一个最明智的操作,并假设该字段映射到一个oid列。事实证明这不是你想要的。

当然,您可以尝试通过编写以下内容来绕过 Hibernate 对 Postgres 的了解:

@Lob @Column(columnDefinition="bytea") 
byte[] binaryData;
Run Code Online (Sandbox Code Playgroud)

然后你会从 Postgres 或其驱动程序收到错误(我忘了是哪个),因为正如我所说,postgres 驱动程序不支持此功能。

那么该怎么办?

好吧,当然,您可以像上面那样尝试破解 Hibernate Dialect,告诉 Hibernate:

  1. 用于byteaJDBC 类型BLOB,以及
  2. BLOB使用 JDBC 类型BINARY或其他的常用处理方式绑定 JDBC VARBINARY

是的,您仍然可以在 H6 中轻松地完成这项工作。

或者,您知道,您可以删除@Lob在这里没有做任何有用工作的愚蠢注释,并让 Hibernate 将您的字段视为 a varbinary,默认情况下映射到bytea

byte[] binaryData;
Run Code Online (Sandbox Code Playgroud)

现在,看,您在这里所做的事情可能还有更多内容,但是您需要通过实际发布字段的详细信息以及您如何映射它来帮助我。