{"record":{"id":"0f3f61aea0ae5d9a","repo":"apache/shardingsphere","slug":"failed-to-read-java-sql-clob","errorCode":null,"errorMessage":"Failed to read java.sql.Clob","messagePattern":"Failed to read java\\.sql\\.Clob","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/statement/execute/protocol/FirebirdBlobBinaryProtocolValue.java","lineNumber":116,"sourceCode":"            blobId = (Long) value;\n        } else if (value instanceof byte[]) {\n            blobId = register(payload.getConnectionId(), (byte[]) value);\n        } else if (value instanceof Blob) {\n            try {\n                blobId = register(payload.getConnectionId(), readAllBytes(((Blob) value).getBinaryStream()));\n            } catch (final SQLException ex) {\n                throw new IllegalStateException(\"Failed to read java.sql.Blob stream\", ex);\n            } catch (final IOException ex) {\n                throw new IllegalStateException(\"Failed to read java.sql.Blob content\", ex);\n            }\n        } else if (value instanceof Clob) {\n            try {\n                Clob clob = (Clob) value;\n                int len = (int) Math.min(Integer.MAX_VALUE, clob.length());\n                String str = clob.getSubString(1L, len);\n                blobId = register(payload.getConnectionId(), str.getBytes(payload.getCharset()));\n            } catch (final SQLException ex) {\n                throw new IllegalStateException(\"Failed to read java.sql.Clob\", ex);\n            }\n        } else {\n            blobId = register(payload.getConnectionId(), value.toString().getBytes(payload.getCharset()));\n        }\n        \n        payload.writeInt8(blobId);\n    }\n    \n    @Override\n    public int getLength(final FirebirdPacketPayload payload) {\n        return 8;\n    }\n}\n","sourceCodeStart":98,"sourceCodeEnd":130,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/statement/execute/protocol/FirebirdBlobBinaryProtocolValue.java#L98-L130","documentation":"Thrown while serializing a java.sql.Clob parameter for the Firebird wire protocol: reading the Clob (length(), getSubString()) raised SQLException. The proxy converts the Clob to bytes using the connection charset and registers it as a BLOB; any JDBC failure during that read is wrapped in IllegalStateException with the cause attached.","triggerScenarios":"Binding a java.sql.Clob parameter where clob.length() or clob.getSubString(1, len) throws — the Clob's owning connection is closed, the Clob was freed, or the driver cannot serve it in the current transaction state.","commonSituations":"Clobs carried across connection boundaries; free() called before execute; drivers that invalidate temp Clobs on commit (similar lifetime issues as Blob, plus charset conversion via payload.getCharset()).","solutions":["Read the chained SQLException to confirm the lifetime/validity problem","Create, bind, and execute the Clob within one open connection and transaction","Bind String or byte[] instead of java.sql.Clob when the content is in memory","Verify the connection charset can encode the Clob content; encode explicitly with setBytes() if charset behavior is unclear"],"exampleFix":"// before: Clob used after its connection/transaction ended\nps.setClob(1, staleClob);\n\n// after: bind the string directly on a live connection\nps.setString(1, text);","handlingStrategy":"validation","validationCode":"// verify the Clob is servicable on this connection before binding\nprivate static boolean isClobUsable(final Clob clob, final Connection conn) {\n    try {\n        return !conn.isClosed() && clob.length() >= 0;\n    } catch (SQLException ex) {\n        return false;\n    }\n}\n// if (!isClobUsable(clob, conn)) ps.setString(1, reloadedText);","typeGuard":null,"tryCatchPattern":"try {\n    ps.setClob(1, clob);\n} catch (IllegalStateException ex) {\n    if (ex.getCause() instanceof SQLException) {\n        ps.setString(1, readClobAgainFromSource()); // fall back to String binding\n    } else {\n        throw ex;\n    }\n}","preventionTips":["Bind String instead of Clob when the text is in memory","Keep the Clob's transaction open until binding finishes; avoid reusing Clobs across connections"],"tags":["firebird","jdbc","clob","lob-lifetime","serialization"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}