为byte []设置适当的休眠注释

我有一个使用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 破坏了(并且不会修复) postgresql中的这个注释组合时(没有解决方法),我们不得不升级到3.5 。到目前为止,我还没有找到明确的修复程序,但是我确实注意到,如果我只是删除@Lob,它将使用postteasql类型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.type组合(@Lob + byte []被映射)到(在postgresql上)。


这是MaterializedBlobType(SQL类型Blob)的3.5.5.Final版本的代码段。根据Steve的博客,postgresql希望您将流用于bytea(不要问我为什么),并将postgresql的自定义Blob类型用于oid。还请注意,在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 );

 }

}


qq_花开花谢_0
浏览 449回答 3
3回答

天涯尽头无女友

我终于完成了这项工作。它扩展了A. Garcia的解决方案,但是,由于问题出在休眠类型MaterializedBlob类型上,仅映射Blob> bytea是不够的,因此我们需要替换MaterializedBlobType,它可以与休眠破碎的Blob支持一起使用。该实现仅适用于bytea,但是JIRA问题中希望OID的人可以为OID实现提供帮助。可悲的是,在运行时替换这些类型很麻烦,因为它们应该是方言的一部分。如果只有JIRA增强功能进入3.6,那将是可能的。public class PostgresqlMateralizedBlobType extends AbstractSingleColumnStandardBasicType<byte[]> {&nbsp;public static final PostgresqlMateralizedBlobType INSTANCE = new PostgresqlMateralizedBlobType();&nbsp;public PostgresqlMateralizedBlobType() {&nbsp; super( PostgresqlBlobTypeDescriptor.INSTANCE, PrimitiveByteArrayTypeDescriptor.INSTANCE );&nbsp;}&nbsp; public String getName() {&nbsp; &nbsp;return "materialized_blob";&nbsp; }}其中的大部分可能是静态的(getBinder()确实需要一个新实例吗?),但是我不太了解休眠内部,因此这主要是复制+粘贴+修改。public class PostgresqlBlobTypeDescriptor extends BlobTypeDescriptor implements SqlTypeDescriptor {&nbsp; public static final BlobTypeDescriptor INSTANCE = new PostgresqlBlobTypeDescriptor();&nbsp; public <X> ValueBinder<X> getBinder(final JavaTypeDescriptor<X> javaTypeDescriptor) {&nbsp; &nbsp;return new PostgresqlBlobBinder<X>(javaTypeDescriptor, this);&nbsp; }&nbsp; public <X> ValueExtractor<X> getExtractor(final JavaTypeDescriptor<X> javaTypeDescriptor) {&nbsp; &nbsp;return new BasicExtractor<X>( javaTypeDescriptor, this ) {&nbsp; &nbsp; protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {&nbsp;&nbsp; &nbsp; &nbsp; return (X)rs.getBytes(name);&nbsp; &nbsp; }&nbsp; &nbsp;};&nbsp; }}public class PostgresqlBlobBinder<J> implements ValueBinder<J> {&nbsp;private final JavaTypeDescriptor<J> javaDescriptor;&nbsp;private final SqlTypeDescriptor sqlDescriptor;&nbsp;public PostgresqlBlobBinder(JavaTypeDescriptor<J> javaDescriptor, SqlTypeDescriptor sqlDescriptor) {&nbsp;&nbsp; this.javaDescriptor = javaDescriptor; this.sqlDescriptor = sqlDescriptor;&nbsp;}&nbsp;&nbsp;&nbsp;...&nbsp;public final void bind(PreparedStatement st, J value, int index, WrapperOptions options)&nbsp;&nbsp;throws SQLException {&nbsp; st.setBytes(index, (byte[])value);&nbsp;}}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java