У меня есть приложение, использующее аннотации 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 (без обходного пути). Я пока не нашел четкого исправления, но заметил, что если я просто удалю @Lob, он будет использовать bytea типа postgresql (который работает, но только на postgres).
annotation postgres oracle works on
-------------------------------------------------------------
byte[] + @Lob oid blob oracle
byte[] bytea raw(255) postgresql
byte[] + @Type(PBA) oid blob oracle
byte[] + @Type(BT) bytea blob postgresql
once you use @Type, @Lob seems to not be relevant
note: oracle seems to have deprecated the "raw" type since 8i.
Я ищу способ иметь один аннотированный класс (со свойством blob), который можно переносить в основные базы данных.
- Каков переносимый способ аннотировать свойство byte []?
- Исправлено ли это в какой-нибудь последней версии гибернации?
Обновление: после прочтения этого блога я, наконец, понял, каким было исходное решение проблемы 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 type Blob). Согласно блогу Стива, postgresql хочет, чтобы вы использовали Streams для bytea (не спрашивайте меня, почему) и пользовательский тип Blob postgresql для 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».
Ссылки:
- https://forum.hibernate.org/viewtopic.php?p=2393203
- https://forum.hibernate.org/viewtopic.php?p=2435174
- http://hibernate.atlassian.net/browse/HHH-4617
- http://postgresql.1045698.n5.nabble.com/Migration-to-Hibernate-3-5-final-td2175339.html
- https://jira.springframework.org/browse/SPR-2318
- https://forums.hibernate.org/viewtopic.php?p=2203382&sid=b526a17d9cf60a80f13d40cf8082aafd
- http://virgo47.wordpress.com/2008/06/13/jpa-postgresql-and-bytea-vs-oid-type/