hibernate/hibernate-orm · error · IllegalStateException
Blobs may not be accessed after serialization
Error message
Blobs may not be accessed after serialization
What it means
SerializableBlobProxy adds java.io.Serializable to a Blob via a JDK dynamic proxy, but the wrapped Blob field is declared transient: only the proxy shell survives Java serialization. After a serialization round trip the field is null, so getWrappedBlob() - and therefore every Blob method routed through invoke() - throws IllegalStateException("Blobs may not be accessed after serialization"). The underlying bytes were never part of the serial form.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/proxy/SerializableBlobProxy.java:47
/**
* Builds a serializable {@link Blob} wrapper around the given {@link Blob}.
*
* @param blob The {@link Blob} to be wrapped.
* @see #generateProxy(Blob)
*/
private SerializableBlobProxy(Blob blob) {
this.blob = blob;
}
/**
* Access to the wrapped Blob reference
*
* @return The wrapped Blob reference
*/
public Blob getWrappedBlob() {
if ( blob == null ) {
throw new IllegalStateException( "Blobs may not be accessed after serialization" );
}
else {
return blob;
}
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ( "getWrappedBlob".equals( method.getName() ) ) {
return getWrappedBlob();
}
try {
return method.invoke( getWrappedBlob(), args );
}
catch ( AbstractMethodError e ) {
throw new HibernateException( "The JDBC driver does not implement the method: " + method, e );
}
catch ( InvocationTargetException e ) {View on GitHub (pinned to fad1729dce)
Solutions
- Map the attribute as byte[] instead of Blob so the raw data itself is serialized
- Do not carry the entity across serialization - reload it by id in the new session/transaction
- If you must serialize, extract first (blob.getBytes(1, (int) blob.length())) and rebuild with Hibernate.getLobHelper().createBlob(bytes)
- Keep Hibernate-managed LOBs inside the owning session's lifetime only
Example fix
// before
@Entity class Doc { @Lob Blob content; } // proxied Blob stored in HttpSession ->
session.setAttribute("doc", doc); // after failover: IllegalStateException
// after
@Entity class Doc {
@Lob byte[] content; // plain serializable data; set via blob.getBytes(1, (int) blob.length())
} Defensive patterns
Strategy: validation
Validate before calling
// Run BEFORE serializing anything that might hold a Hibernate Blob proxy
static byte[] detachBlob(java.sql.Blob blob) throws SQLException {
try {
return blob.getBytes(1, (int) blob.length()); // works on the live proxy
} catch (IllegalStateException e) {
throw new IllegalStateException(
"Blob already deserialized/empty - reload the entity in this session", e);
}
}
// store detachBlob(blob) in the session/cache instead of the proxy Try / catch
try {
byte[] data = blob.getBytes(1, (int) blob.length());
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("after serialization")) {
// the lob is gone: the only correct recovery is re-fetching the row
entity = session.find(Entity.class, id);
data = entity.getContent();
} else {
throw e;
}
} Prevention
- Map LOB columns as byte[]/String in entities that will be serialized (HTTP session, caches, queues)
- Never place Hibernate-managed LOB proxies in replicated sessions or store-by-value caches
- Keep LOB-bearing entities within one session; reload by id in the next one
- Materialize lob content to byte[] before any Java-serialization boundary
When it happens
Trigger: Storing a Hibernate-proxied Blob in an HttpSession that gets passivated/replicated (Spring Session, cluster failover); putting a detached entity containing the proxy into a store-by-value cache (ehcache/Infinispan in that mode); RMI or Java-serialization of the entity; calling ((WrappedBlob) proxy).getWrappedBlob() after deserialization.
Common situations: Web apps saving Hibernate entities with Blob fields in the HTTP session across clustered nodes; serializing detached entities into queues or distributed caches; JSF view state holding entities; any architecture that ships entities between JVMs via Java serialization.
Related errors
- Clobs may not be accessed after serialization
- Unable to set BLOB bytes after creation
- Could not create JDBC Blob
- Start position 1-based; must be 1 or more.
- Length must be great-than-or-equal to zero.
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/a84cabfd08a44a4c.
Report an issue: GitHub.