We have an entity with a property of java.io.Serializable type mapped to a BLOB column in Oracle 11.2.0 db. We need to store byte[] into this column. If we did this in any Hibernate version before 4.3.0.Beta4, Hibernate stored the value as serialized Java object. In all later Hibernate versions (incl. 4.3.0.Beta4) the value is stored as it is (pure byte array).
We found that the cause of this difference is in org.hibernate.type.descriptor.java.SerializableTypeDescriptor where following method is called during persisting of an entity:
@SuppressWarnings( {"unchecked"}
) public <X> X unwrap(T value, Class<X> type, WrapperOptions options) { if (value == null) { return null; }
else if (type.isInstance(value)) { return (X) value; }
else if (byte[].class.isAssignableFrom(type)) { return (X) toBytes(value); }
else if (InputStream.class.isAssignableFrom(type)) { return (X) new ByteArrayInputStream(toBytes(value)); }
else if (BinaryStream.class.isAssignableFrom(type)) { return (X) new BinaryStreamImpl(toBytes(value)); }
else if (Blob.class.isAssignableFrom(type)) { return (X) options.getLobCreator().createBlob(toBytes(value)); }
throw unknownUnwrap(type); }
In Hibernate versions before 4.3.0.Beta4 this method had missing 2 lines lines:
} else if (type.isInstance(value)) { return (X) value;
Thus, when attempted to store byte[], following happens: 1. in Hibernate versions before 4.3.0.Beta4 method passes the condition "if (byte[].class.isAssignableFrom(type))" and therefore executes "return (X) toBytes(value);" 2. in Hibernate versions after 4.3.0.Beta4 method passes already the condition "if (type.isInstance(value))" and therefore executes "return (X) value;"
Note: In point #1 above the "toBytes(value)" method calls org.hibernate.internal.util.SerializationHelper.serialize(Serializable obj).
Our question is: was this intended or is this a bug? We already have stored byte arrays in production environment using Hibernate versions older than 4.3.0.Beta4, so these values are in serialized Java form. After switching to any newer Hibernate version we're not able to load these values because Hibernate wants to treat them as pure byte array. This problem's description might be similar to
HHH-8111
.
Thanks for the explanation.
|