правильная аннотация спящего режима для байта []

У меня есть приложение, использующее аннотации hibernate 3.1 и JPA. В нем есть несколько объектов с атрибутами byte [] (размером от 1k до 200k). Он использует аннотацию JPA @Lob, и hibernate 3.1 может нормально читать их во всех основных базах данных - похоже, он скрывает особенности поставщика JDBC Blob (как и должно быть).

@Entity
public class ConfigAttribute {
  @Lob
  public byte[] getValueBuffer() {
    return m_valueBuffer;
  }
}

Нам пришлось перейти на 3.5, когда мы обнаружил, что hibernate 3.5 нарушает (и не исправляет) эту комбинацию аннотаций в postgresql (без обходного пути). Я пока не нашел четкого решения, Прочитав этот блог , я, наконец, понял, каков был исходный обходной путь в проблеме JIRA: по-видимому, вы должны отказаться от @Lob и аннотировать свойство следующим образом:

@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType") 
byte[] getValueBuffer() {...

Однако это не работает для меня - я все равно получаю OID вместо bytea; Однако это сработало для автора проблемы JIRA, который, похоже, хотел использовать oid.

После ответа А. Гарсиа я затем попробовал эту комбинацию, которая действительно работает на postgresql, но не на oracle.

@Type(type="org.hibernate.type.BinaryType") 
byte[] getValueBuffer() {...

Что мне действительно нужно сделать, так это указать, какие @ org.hibernate.annotations. Введите комбинацию (@Lob + byte [] отображается) в (на postgresql).


Вот фрагмент из 3.5.5.Final из MaterializedBlobType (sql тип Blob). Согласно блогу Стива, postgresql хочет, чтобы вы использовали Streams для bytea (не спрашивайте меня, почему) и postgresql ' s настраиваемый тип Blob для oids. Также обратите внимание, что использование setBytes () в JDBC также предназначено для bytea (из прошлого опыта). Таким образом, это объясняет, почему потоки использования не имеют никакого влияния, они оба принимают «bytea».

public void set(PreparedStatement st, Object value, int index) {
 byte[] internalValue = toInternalFormat( value );
 if ( Environment.useStreamsForBinary() ) {
  // use streams = true
   st.setBinaryStream( index, 
    new ByteArrayInputStream( internalValue ), internalValue.length );
 }
 else {
  // use streams = false
  st.setBytes( index, internalValue );
 }
}

Это приводит к:

ERROR: column "signature" is of type oid but expression is of type bytea

Обновление Следующий логичный вопрос: «Почему бы просто не изменить определения таблиц вручную на bytea» и сохранить (@Lob + byte [])? Этот выполняет работу, ДО вы пытаетесь сохранить нулевой байт []. Драйвер postgreSQL считает, что это выражение типа OID, а тип столбца - bytea - это потому, что hibernate (правильно) вызывает JDBC.setNull () вместо JDBC.setBytes (null), который ожидает драйвер PG.

ERROR: column "signature" is of type bytea but expression is of type oid

Система типов в спящем режиме в настоящее время находится в стадии разработки (согласно устаревшему комментарию 3.5.5). Фактически, так много кода 3.5.5 устарело, трудно понять, на что обращать внимание при подклассе PostgreSQLDialect).

AFAKT, Types.BLOB / 'oid' в postgresql должны быть сопоставлены с некоторым настраиваемым типом, который использует доступ JDBC в стиле OID (т.е. объект PostgresqlBlobType, а НЕ MaterializedBlobType). На самом деле я никогда успешно не использовал Blobs с postgresql, но я знаю, что bytea просто работает так, как я ожидал.

В настоящее время я смотрю на исключение BatchUpdateException - возможно, драйвер не поддерживает пакетную обработку.


Отличная цитата 2004 года: «Подводя итог своим рассуждениям, я бы сказал, что мы должны дождаться, пока драйвер JDBC выполнит правильные операции с большими объектами, прежде чем менять Hibernate».

Ссылки:

21
задан kennytm 9 September 2010 в 15:53
поделиться