对字节的正确休眠注释[]
我有一个使用休眠3.1和JPA注释的应用程序。它有一些具有byte[]属性的对象(大小为1k - 200k)。它使用JPA@Lob注释,而休眠3.1可以在所有主要数据库上很好地读取这些内容 - 它似乎隐藏了JDBC Blob供应商的特殊性(正如它应该做的那样)。
@Entity
public class ConfigAttribute {
@Lob
public byte[] getValueBuffer() {
return m_valueBuffer;
}
}
当我们发现休眠3.5在postgresql中中断(并且不会修复)这个注释组合时,我们不得不升级到3.5(并且没有解决方法)。到目前为止,我还没有找到一个明确的修复程序,但我确实注意到,如果我只是删除@Lob,它使用postgresql类型bytea(有效,但仅适用于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。
在A. Garcia的答案之后,我尝试了这个组合,它实际上在postgresql上起作用,但在oracle上不起作用。
@Type(type="org.hibernate.type.BinaryType")
byte[] getValueBuffer() {...
我真正需要做的是控制哪个@org.hibernate.annotations.键入组合(@Lob + byte[]被映射到)到(在postgresql上)。
下面是来自 3.5.5.Final 的片段,来自 MaterializedBlobType(sql 类型 Blob)。根据Steve的博客,postgresql希望你使用Streams for bytea(不要问我为什么)和postgresql的自定义Blob类型。还要注意,在 JDBC 上使用 setBytes() 也适用于 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()而不是PG驱动程序期望的JDBC.setBytes(null)。
ERROR: column "signature" is of type bytea but expression is of type oid
休眠状态的类型系统目前是“正在进行的工作”(根据 3.5.5 弃用注释)。事实上,3.5.5 代码中有很多东西被弃用了,很难知道在对 PostgreSQLDialect 进行子类化时要看什么)。
AFAKT, Types.BLOB/'oid' on postgresql 应该映射到一些使用 OID 样式 JDBC 访问的自定义类型(即 PostgresqlBlobType 对象和 NOT MaterializedBlobType)。我从未真正成功地将Blobs与postgresql一起使用,但我确实知道bytea只是简单地工作/我所期望的。
我目前正在查看 BatchUpdateException - 驱动程序可能不支持批处理。
2004年的一句话:“总结一下我的闲言碎语,我想说的是,我们应该等待JDBC驱动程序在更改Hibernate之前正确执行LOB。
引用:
- 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/