{"record":{"id":"1ddb49759c26339b","repo":"hibernate/hibernate-orm","slug":"ioexception-occurred-reading-a-binary-value-1ddb49","errorCode":null,"errorMessage":"IOException occurred reading a binary value","messagePattern":"IOException occurred reading a binary value","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobJavaType.java","lineNumber":137,"sourceCode":"\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\tif ( Blob.class.isAssignableFrom( type ) ) {\n\t\t\t\treturn type.cast( options.getLobCreator().toJdbcBlob( value ) );\n\t\t\t}\n\t\t\telse if ( byte[].class.isAssignableFrom( type )) {\n\t\t\t\tif (value instanceof BlobImplementer blobImplementer) {\n\t\t\t\t\t// if the incoming Blob is a wrapper, just grab the bytes from its BinaryStream\n\t\t\t\t\treturn type.cast( blobImplementer.getUnderlyingStream().getBytes() );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// otherwise extract the bytes from the stream manually\n\t\t\t\t\t\treturn type.cast( value.getBinaryStream().readAllBytes() );\n\t\t\t\t\t}\n\t\t\t\t\tcatch ( IOException e ) {\n\t\t\t\t\t\tthrow new HibernateException( \"IOException occurred reading a binary value\", e );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( BinaryStream.class.isAssignableFrom( type ) ) {\n\t\t\t\tif (value instanceof BlobImplementer blobImplementer) {\n\t\t\t\t\treturn type.cast( blobImplementer.getUnderlyingStream() );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn type.cast( new StreamBackedBinaryStream( value.getBinaryStream(), value.length() ) );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( InputStream.class.isAssignableFrom( type ) ) {\n\t\t\t\tif (value instanceof BlobImplementer blobImplementer) {\n\t\t\t\t\t// if the incoming Blob is a wrapper, just pass along its BinaryStream\n\t\t\t\t\treturn type.cast( blobImplementer.getUnderlyingStream().getInputStream() );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// otherwise we need to build a BinaryStream...","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobJavaType.java#L119-L155","documentation":"Thrown by BlobJavaType.unwrap when a raw (non-BlobImplementer) Blob is converted to byte[]: it calls value.getBinaryStream().readAllBytes() and an IOException during the read is wrapped in HibernateException('IOException occurred reading a binary value'). Unlike the SQLException variants, this means the stream opened but broke mid-read: connection dropped, stream closed underneath, or the driver could not deliver the full LOB payload.","triggerScenarios":"unwrap(..., byte[].class) on a plain JDBC Blob (loading a byte[] attribute from a BLOB column without Hibernate's wrapper); reading a large BLOB when the socket times out or the connection is invalidated mid-stream; reading the stream after it was already consumed or the statement was closed.","commonSituations":"Large binary columns (documents, images) exceeding socket/driver buffer or timeout settings; pool eviction (idle-in-transaction) while streaming a LOB; load-after-commit access patterns.","solutions":["Keep the session/transaction open until the byte[] has been fully read.","Raise driver/pool timeouts (socketTimeout, connection idle timeout) for connections that stream large LOBs.","Map byte[] directly with @Lob so Hibernate materializes the value during the row read.","If the connection was invalidated, retry the load once on a fresh session."],"exampleFix":"// before\n@Lob private java.sql.Blob data;\nbyte[] bytes = entity.getData().getBinaryStream().readAllBytes(); // after tx -> IOException\n\n// after\n@Lob private byte[] data; // materialized eagerly by Hibernate\nbyte[] bytes = entity.getData();","handlingStrategy":"retry","validationCode":"// fail fast if the connection is already suspect\nif (!connection.isValid(2)) throw new IllegalStateException(\"Connection unhealthy; reload instead of streaming LOB\");","typeGuard":null,"tryCatchPattern":"try {\n    bytes = blob.getBinaryStream().readAllBytes();\n} catch (IOException | HibernateException e) {\n    // stream broke mid-read: one retry on a fresh session is usually enough\n    return retryInNewSession(id);\n}","preventionTips":["Size socket/pool timeouts above your largest LOB transfer time.","Read LOB columns in the same statement/transaction as the load.","Stream very large BLOBs chunked instead of readAllBytes in one shot."],"tags":["hibernate","blob","lob","io","jdbc"],"backgroundTag":"blob-stream-access","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}