hibernate/hibernate-orm · error · JDBCException

Could not create JDBC NClob

Error message

Could not create JDBC NClob

What it means

Thrown by BlobAndClobCreator.toJdbcNClob when Hibernate converts an existing java.sql.NClob into a JDBC NClob. With connection-based LOB creation enabled, Hibernate calls clob.getSubString(1, (int) clob.length()) and Connection.createNClob(String); any SQLException is rethrown as a JDBCException with this message.

Source

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

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

View on GitHub (pinned to fad1729dce)

Solutions

  1. Materialize the value as a String (or lobHelper.createNClob(String)) while the source connection is open and bind that instead
  2. Map the attribute as a nationalized String (@Nationalized String) and let Hibernate handle wrapping
  3. Check the underlying SQLException for the driver error; grant required LOB privileges and verify national charset setup
  4. Upgrade the JDBC driver / database client library

Example fix

// before
entity.setNdoc(nclobFromClosedConnection);

// after
String text = nclob.getSubString(1, (int) nclob.length());
entity.setNdoc(session.getLobHelper().createNClob(text));
Defensive patterns

Strategy: try-catch

Validate before calling

// verify NClob is usable before binding (locator still valid)
try {
    if (nclob.length() >= 0) { /* locator alive */ }
}
catch (SQLException e) {
    // materialize from a fresh read or fail fast
}

Try / catch

try {
    session.persist(entity);
    session.flush();
}
catch (JDBCException e) {
    // e.getSQLException() carries the driver error for createNClob/getSubString
    log.warn("NCLOB conversion failed: {}", e.getSQLException(), e);
}

Prevention

When it happens

Trigger: Binding a nationalized character value as java.sql.NClob when the source NClob locator is already freed (owning connection committed/closed), when the driver's createNClob fails, or when the content exceeds Integer.MAX_VALUE characters.

Common situations: Using @Nationalized properties or NCHAR/NVARCHAR2 columns with drivers that invalidate NClob locators after transaction commit; reusing NClobs read in a previous request; missing national character set support in the DB or driver.

Related errors


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