I've a credit card applicatoin using hibernate 3.1 and JPA annotations. It features a couple of objects with byte[] characteristics (1k - 200k in dimensions). It uses the JPA @Lob annotation, and hibernate 3.1 can see most fine on all major databases -- it appears to cover the JDBC Blob vendor peculiarities (because it must do).

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

We needed to upgrade to three.5, whenever we learned that hibernate 3.5 breaks (and will not fix) this annotation combination in postgresql (without any workaround). I haven't found a obvious fix to date, however i did observe that basically just take away the @Lob, it uses the postgresql type bytea (which works, only on 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.

I'm searching for a method to possess a single annotated class (having a blob property) that is portable across major databases.

  • What's the portable method to annotate a byte[] property?
  • Is fixed in certain recent version of hibernate?

Update: After reading through this web site I've finally determined exactly what the original workaround within the JIRA problem was: Apparently you are meant to drop @Lob and annotate the home as:

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

However, this doesn't work for me personally -- I get OIDs rather than bytea it did however work with the writer from the JIRA problem, who appeared to wish oid.

Following the answer from the. Garcia, Then i attempted this combo, which really works on postgresql, but this is not on oracle.

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

Things I really should do is control which @org.hibernate.annotations.Type the mixture (@Lob + byte[] will get planned) to (on postgresql).


This is actually the snippet from three.5.5.Final from MaterializedBlobType (sql type Blob). Based on Steve's blog, postgresql wants you to employ Streams for bytea (don't request me why) and postgresql's custom Blob type for oids. Note additionally that using setBytes() on JDBC can also be for bytea (from consider your experience). Which means this describes why would you use-streams doesn't have affect both of them assume '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 );
 }
}

This leads to:

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

Update The following logical real question is: "why don't you just alter the table definitions by hand to bytea" and the (@Lob + byte[])? This does work, UNTIL you attempt to keep a null byte[]. That the postgreSQL driver thinks is definitely an OID type expression and also the column type is bytea -- the reason being hibernate (appropriately) calls JDBC.setNull() rather than JDBC.setBytes(null) which PG driver needs.

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

The kind system in hibernate is presently a 'work in progress' (based on 3.5.5 deprecation comment). Actually a lot of the three.5.5 code is deprecated, it's hard to be aware what to check out when sub-classing the PostgreSQLDialect).

AFAKT, Types.BLOB/'oid' on postgresql ought to be planned with a custom type which utilizes OID style JDBC access (i.e. PostgresqlBlobType object and never MaterializedBlobType). I have never really effectively used Blobs with postgresql, but I know that bytea simply works as you / I'd expect.

I'm presently searching in the BatchUpdateException -- its likely the driver does not support batching.


Great quote from 2004: "To summarize my ramblings, I'd say they we ought to wait for a JDBC driver to complete LOBs correctly before altering Hibernate."

References: