Hibernate, Postgresql: столбец "x" имеет тип oid, но выражение имеет тип byte

У меня странная проблема, связанная с отображением гибернации, содержащей большие объекты (BLOB), при переключении между различными базами данных.

@Lob
private byte[] binaryData;

Поле выше создает поле байтового массива в MySQL и в Oracle, однако в PostreSQL оно создает поле типа oid.

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

Column "binaryData" is of type oid but expression is of type bytea.

Поэтому я попытался просто удалить аннотацию "@Lob", что решит проблему для PostgreSQL, однако в MySQL без этой аннотации hibernate создает поле типа "tinyblob", которое в большинстве случаев является небольшим. И, поскольку мы хотим использовать этот проект в более чем одной среде, раздражает необходимость переключения двух разных отображений.

Есть ли аннотация, которая заставляет postgreSQL использовать bytea вместо oid для полей, аннотированных @Lob? Или как-то можно опустить @Lob и поместить что-то еще, чтобы заставить MySQL выделить его с большим типом данных, как это было бы при использовании @Lob?

Я мог бы даже представить себе такое решение

if (field is of type oid)
  store it as oid
else if (field is of type bytea)
  store it as bytea
else
  // not storable

и так же, как добытчик, если существует способ сделать вид этого

РЕДАКТИРОВАТЬ:

Следующая декларация работает. Он выделяет столбец как oid, однако в режиме гибернации он умеет хранить и извлекать данные из такого поля.

@Lob
@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType")
private byte[] binaryFile;

5 ответов

Решение

Это отображение поля определено в org.hibernate.dialect.PostgreSQLDialect и может быть изменено путем подкласса этого и настройки вашего приложения на использование измененного диалекта при работе с postgres.

Соответствующее заклинание в подклассе, вероятно,

    registerColumnType( Types.BLOB, "bytea" );

в вашем конструкторе после вызова super(),

Гибернация 6+, Javaee 9+

        @Lob
  @JdbcTypeCode(Types.BINARY)
  private byte[] binaryData;

Для меня это могло означать, что однажды "верните обратно свою версию postgres jdbc обратно в 9.3-1101.jdbc4"

  <dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>9.4-1200-jdbc41</version>
  </dependency>

работал также. Новее, чем это не удалось...

Этот класс устарел с Hibernate 3.6. Теперь с последней версией Hibernate нам нужно использовать @Type(type="org.hibernate.type.MaterializedBlobType")вместо. Пожалуйста, проверьте https://docs.jboss.org/hibernate/core/3.6/javadocs/deprecated-list.html и https://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/type/MaterializedBlobType.html для получения дополнительной информации.

Большие объекты PostgreSQL имеют тип , так как фактически являются ссылками на объекты в отдельной таблице, pg_largeobject_metadata.

Карты интерфейса JDBC oidк java.sql.Types.DISTINCT.

Ни один из диалектов Hibernate не знает, что это тип Blob, но вы можете указать свой собственный, который рассматривает их как эквивалентные:

      public static class PostgreSQLDialect extends PostgreSQL10Dialect {
    @Override
    public boolean equivalentTypes(int type1, int type2) {
        return super.equivalentTypes(type1, type2) ||
                (type1 == Types.BLOB && type2 == Types.DISTINCT) ||
                (type1 == Types.DISTINCT && type2 == Types.BLOB);
    }
}
Другие вопросы по тегам