hibernate/hibernate-orm · error · JDBCException
Could not create JDBC Blob
Error message
Could not create JDBC Blob
What it means
BlobAndClobCreator.toJdbcBlob converts a Blob into a JDBC-usable form: with useConnectionToCreateLob it reads all bytes via blob.getBytes(1, (int) blob.length()) and writes them into a freshly created JDBC Blob; otherwise it delegates to the non-contextual parent. Any SQLException on that path is wrapped as JDBCException('Could not create JDBC Blob'). Note the (int) cast on length(): BLOBs larger than Integer.MAX_VALUE overflow before the driver is even reached.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/BlobAndClobCreator.java:172
* Obtain a {@link Blob} instance which can be written to a JDBC
* {@link java.sql.PreparedStatement} using
* {@link java.sql.PreparedStatement#setBlob(int, Blob)}.
*/
@Override
public Blob toJdbcBlob(Blob blob) {
try {
if ( useConnectionToCreateLob ) {
// final Blob jdbcBlob = createBlob();
// blob.getBinaryStream().transferTo( jdbcBlob.setBinaryStream(1) );
// return jdbcBlob;
return createBlob( blob.getBytes( 1, (int) blob.length() ) );
}
else {
return super.toJdbcBlob( blob );
}
}
catch (SQLException e) {
throw new JDBCException( "Could not create JDBC Blob", e );
}
// catch (IOException e) {
// throw new HibernateException( "Could not create JDBC Blob", e );
// }
}
/**
* Obtain a {@link Clob} instance which can be written to a JDBC
* {@link java.sql.PreparedStatement} using
* {@link java.sql.PreparedStatement#setClob(int, Clob)}.
*/
@Override
public Clob toJdbcClob(Clob clob) {
try {
if ( useConnectionToCreateLob ) {
// final Clob jdbcClob = createClob();
// clob.getCharacterStream().transferTo( jdbcClob.setCharacterStream(1) );
// return jdbcClob;View on GitHub (pinned to fad1729dce)
Solutions
- Enable hibernate.jdbc.lob.non_contextual_creation=true to use the non-contextual parent path (stream-based binding, no byte[] copy)
- Upgrade the JDBC driver if createBlob()/setBytes() is the failing link
- For BLOBs over 2GB, bind via setBinaryStream/stream LobCreator paths instead of toJdbcBlob
- Check the wrapped SQLException to identify which call failed (getBytes vs setBytes)
Example fix
# before: contextual path, byte[] copy (also caps at 2GB via (int) cast) <property name="hibernate.jdbc.lob.non_contextual_creation" value="false"/> # after <property name="hibernate.jdbc.lob.non_contextual_creation" value="true"/>
Defensive patterns
Strategy: fallback
Validate before calling
// guard the 2GB int-overflow and driver weakness before converting
if ( blob.length() > Integer.MAX_VALUE ) {
throw new IllegalArgumentException("BLOB exceeds 2GB; bind via stream instead of toJdbcBlob");
} Try / catch
try {
return lobCreator.toJdbcBlob(blob);
} catch (JDBCException e) {
// fall back to stream binding, bypassing the byte[] copy entirely
ps.setBinaryStream(index, blob.getBinaryStream(), blob.length());
} Prevention
- Enable hibernate.jdbc.lob.non_contextual_creation=true to avoid the byte[] copy path entirely
- For very large BLOBs, prefer setBinaryStream-style binding over Blob conversion
When it happens
Trigger: Binding a Blob to a PreparedStatement while contextual creation is enabled and either the read/create/write path throws SQLException, or blob.length() exceeds Integer.MAX_VALUE and the cast silently truncates/overflows the read length.
Common situations: Drivers whose createBlob/setBytes path fails (same root causes as errors 1317/1318); attempted binding of multi-gigabyte BLOBs; using a stale LobCreator after its connection closed.
Related errors
- Unable to set BLOB bytes after creation
- Can't deal with Blobs larger than 'Integer.MAX_VALUE'
- Unable to set CLOB string after creation
- 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/4a7a69a1076f23fa.
Report an issue: GitHub.