hibernate/hibernate-orm · error · HibernateException
Unable to access lob stream
Error message
Unable to access lob stream
What it means
DataHelper.extractString(Clob) opens value.getCharacterStream() and asks the Clob for its length (determineLengthForBufferSizing, backed by Clob.length()); any SQLException from those calls is wrapped as HibernateException('Unable to access lob stream'). This fails before a single character is read — the driver refused to hand out or measure the LOB.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DataHelper.java:261
}
/**
* Extract the contents of the given Clob as a string.
*
* @param value The clob to to be extracted from
*
* @return The content as string
*/
public static String extractString(final Clob value) {
try {
final var characterStream = value.getCharacterStream();
final long length = determineLengthForBufferSizing( value );
return length > Integer.MAX_VALUE
? extractString( characterStream, Integer.MAX_VALUE )
: extractString( characterStream, (int) length );
}
catch ( SQLException e ) {
throw new HibernateException( "Unable to access lob stream", e );
}
}
/**
* Determine a buffer size for reading the underlying character stream.
*
* @param value The Clob value
*
* @return The appropriate buffer size ({@link Clob#length()} by default.
*
*/
private static long determineLengthForBufferSizing(Clob value) throws SQLException {
try {
return value.length();
}
catch ( SQLFeatureNotSupportedException e ) {
return BUFFER_SIZE;
}View on GitHub (pinned to fad1729dce)
Solutions
- Convert the Clob to String while the connection and transaction are alive — materialize before detaching
- Never hold Clob objects in long-lived state; store the extracted String instead
- Check that nothing (code, pool wrapper, driver) called Clob.free() before the read
- Upgrade the JDBC driver if its Clob implementation lacks stream support
Example fix
// before Clob c = rs.getClob(1); // ... later, after tx commit String s = extractText(c); // SQLException -> Unable to access lob stream // after Clob c = rs.getClob(1); String s = c.getSubString(1, (int) c.length()); // materialize immediately, detach the String
Defensive patterns
Strategy: try-catch
Try / catch
try {
String s = DataHelper.extractString(clob);
} catch (HibernateException e) {
if (e.getCause() instanceof SQLException se) {
// lob freed/closed or connection gone: re-fetch the row in a fresh tx
}
} Prevention
- Materialize LOBs to String/byte[] before detaching entities
- Never call Clob.free() while Hibernate may still read it
- Keep LOB reads inside the owning transaction
When it happens
Trigger: Clob.getCharacterStream() or Clob.length() throwing: the LOB was already freed or closed (Oracle frees temporary LOBs at transaction end), the connection is closed, something called Clob.free() prematurely, or the driver's Clob implementation does not support the call.
Common situations: Detached entities or web requests carrying Clob objects across transaction boundaries; proxying or wrapping JDBC objects; keeping Clob references in caches or HTTP sessions.
Related errors
- Unable to set CLOB string after creation
- Could not create JDBC Clob
- Start position 1-based; must be 1 or more.
- Start position [${start}] cannot exceed overall CLOB length
- 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/dc62b27e28c5562b.
Report an issue: GitHub.