hibernate/hibernate-orm · error · JDBCException

Could not create JDBC Clob

Error message

Could not create JDBC Clob

What it means

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.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/BlobAndClobCreator.java:198

	 * 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;
				return createClob( clob.getSubString( 1, (int) clob.length() ) );
			}
			else {
				return super.toJdbcClob( clob );
			}
		}
		catch (SQLException e) {
			throw new JDBCException( "Could not create JDBC Clob", e );
		}
//		catch (IOException e) {
//			throw new HibernateException( "Could not create JDBC Clob", e );
//		}
	}

	/**
	 * Obtain an {@link NClob} instance which can be written to a JDBC
	 * {@link java.sql.PreparedStatement} using
	 * {@link java.sql.PreparedStatement#setNClob(int, NClob)}.
	 */
	@Override
	public NClob toJdbcNClob(NClob clob) {
		try {
			if ( useConnectionToCreateLob ) {
//				final NClob jdbcClob = createNClob();
//				clob.getCharacterStream().transferTo( jdbcClob.setCharacterStream(1) );
//				return jdbcClob;

View on GitHub (pinned to fad1729dce)

Solutions

  1. 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)
  2. Keep the Session and its connection open until the flush that binds the Clob completes; do not reuse Clobs across transactions
  3. Inspect the wrapped SQLException (getCause()) to see the driver-level reason and fix privileges/driver accordingly
  4. Upgrade the JDBC driver if Connection.createClob is known to be buggy for your database version

Example fix

// before: locator-backed Clob reused after its connection closed
entity.setDoc(clobFromPreviousSession); // fails at flush

// after: materialize while the source connection is open
String text = clob.getSubString(1, (int) clob.length());
entity.setDoc(session.getLobHelper().createClob(text));
Defensive patterns

Strategy: try-catch

Validate before calling

// materialize while the owning connection is alive, before binding
String text;
try {
    text = clob.getSubString(1, (int) clob.length());
}
catch (SQLException e) {
    throw new IllegalStateException("source Clob no longer valid", e);
}
entity.setText(text); // String/@Lob mapping avoids locator issues

Try / catch

try {
    session.persist(entity);
    session.flush();
}
catch (JDBCException e) {
    SQLException sql = e.getSQLException();
    // inspect sql.getErrorCode()/SQLState for the driver-level LOB failure
    log.warn("LOB bind failed: {}", sql, e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/f313120b6bb74443. Report an issue: GitHub.