{"record":{"id":"f313120b6bb74443","repo":"hibernate/hibernate-orm","slug":"could-not-create-jdbc-clob","errorCode":null,"errorMessage":"Could not create JDBC Clob","messagePattern":"Could not create JDBC Clob","errorType":"exception","errorClass":"JDBCException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/BlobAndClobCreator.java","lineNumber":198,"sourceCode":"\t * Obtain a {@link Clob} instance which can be written to a JDBC\n\t * {@link java.sql.PreparedStatement} using\n\t * {@link java.sql.PreparedStatement#setClob(int, Clob)}.\n\t */\n\t@Override\n\tpublic Clob toJdbcClob(Clob clob) {\n\t\ttry {\n\t\t\tif ( useConnectionToCreateLob ) {\n//\t\t\t\tfinal Clob jdbcClob = createClob();\n//\t\t\t\tclob.getCharacterStream().transferTo( jdbcClob.setCharacterStream(1) );\n//\t\t\t\treturn jdbcClob;\n\t\t\t\treturn createClob( clob.getSubString( 1, (int) clob.length() ) );\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn super.toJdbcClob( clob );\n\t\t\t}\n\t\t}\n\t\tcatch (SQLException e) {\n\t\t\tthrow new JDBCException( \"Could not create JDBC Clob\", e );\n\t\t}\n//\t\tcatch (IOException e) {\n//\t\t\tthrow new HibernateException( \"Could not create JDBC Clob\", e );\n//\t\t}\n\t}\n\n\t/**\n\t * Obtain an {@link NClob} instance which can be written to a JDBC\n\t * {@link java.sql.PreparedStatement} using\n\t * {@link java.sql.PreparedStatement#setNClob(int, NClob)}.\n\t */\n\t@Override\n\tpublic NClob toJdbcNClob(NClob clob) {\n\t\ttry {\n\t\t\tif ( useConnectionToCreateLob ) {\n//\t\t\t\tfinal NClob jdbcClob = createNClob();\n//\t\t\t\tclob.getCharacterStream().transferTo( jdbcClob.setCharacterStream(1) );\n//\t\t\t\treturn jdbcClob;","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/BlobAndClobCreator.java#L180-L216","documentation":"Thrown by BlobAndClobCreator.toJdbcClob when Hibernate converts an existing java.sql.Clob into a JDBC Clob that can be written through a PreparedStatement. When the dialect/environment says LOBs are created via the connection (useConnectionToCreateLob), Hibernate materializes the value with clob.getSubString(1, (int) clob.length()) and Connection.createClob(String); any SQLException from those calls is wrapped in a JDBCException with this message.","triggerScenarios":"Persisting or binding an attribute of type java.sql.Clob while the source Clob is invalid: its LOB locator was freed (connection/transaction that produced it already committed or closed), Connection.createClob() fails on the driver, or the Clob is larger than Integer.MAX_VALUE so the (int) length cast/getSubString fails.","commonSituations":"Copying a Clob read in one transaction into an entity saved by another session; detaching entities that hold locator-backed Clobs; older Oracle/Sybase drivers that invalidate LOB locators after commit; DB users lacking LOB creation privileges.","solutions":["Materialize the value into a String or a Hibernate-created Clob while the owning connection is still open (e.g. Hibernate.getLobHelper().createClob(text) or map the attribute as String/@Lob)","Keep the Session and its connection open until the flush that binds the Clob completes; do not reuse Clobs across transactions","Inspect the wrapped SQLException (getCause()) to see the driver-level reason and fix privileges/driver accordingly","Upgrade the JDBC driver if Connection.createClob is known to be buggy for your database version"],"exampleFix":"// before: locator-backed Clob reused after its connection closed\nentity.setDoc(clobFromPreviousSession); // fails at flush\n\n// after: materialize while the source connection is open\nString text = clob.getSubString(1, (int) clob.length());\nentity.setDoc(session.getLobHelper().createClob(text));","handlingStrategy":"try-catch","validationCode":"// materialize while the owning connection is alive, before binding\nString text;\ntry {\n    text = clob.getSubString(1, (int) clob.length());\n}\ncatch (SQLException e) {\n    throw new IllegalStateException(\"source Clob no longer valid\", e);\n}\nentity.setText(text); // String/@Lob mapping avoids locator issues","typeGuard":null,"tryCatchPattern":"try {\n    session.persist(entity);\n    session.flush();\n}\ncatch (JDBCException e) {\n    SQLException sql = e.getSQLException();\n    // inspect sql.getErrorCode()/SQLState for the driver-level LOB failure\n    log.warn(\"LOB bind failed: {}\", sql, e);\n}","preventionTips":["Map large text to String or @Lob String instead of java.sql.Clob","Never reuse a Clob obtained from another session/transaction","Keep the session and connection open until flush completes"],"tags":["jdbc","clob","lob","hibernate","persistence"],"backgroundTag":"jdbc-lob-creation-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}