hibernate/hibernate-orm · error · HibernateException

Could not transform the raw jdbc value

Error message

Could not transform the raw jdbc value

What it means

When reading Oracle STRUCT column values through OracleReflectionStructJdbcType, Hibernate keeps per-class transformer Methods for oracle.sql types (TIMESTAMPTZ, TIMESTAMPLTZ, ...) that need the live connection to convert themselves to standard Java types. transformRawJdbcValue invokes that method reflectively; any invocation failure is wrapped in HibernateException. So the real cause is the driver object failing its own conversion - typically a closed/stale connection being passed to the conversion method, session-timezone problems, or an ojdbc version whose internal APIs differ.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/type/OracleReflectionStructJdbcType.java:75

						.getDatabase()
						.getDefaultNamespace()
						.locateUserDefinedType( Identifier.toIdentifier( sqlType ) )
						.getOrderMapping()
		);
	}

	@Override
	protected Object transformRawJdbcValue(Object rawJdbcValue, WrapperOptions options) {
		Method rawJdbcTransformer = RAW_JDBC_TRANSFORMER.get( rawJdbcValue.getClass() );
		if ( rawJdbcTransformer == null ) {
			return rawJdbcValue;
		}
		try {
			return rawJdbcTransformer.invoke( rawJdbcValue,
					options.getSession().getJdbcCoordinator().getLogicalConnection().getPhysicalConnection() );
		}
		catch (Exception e) {
			throw new HibernateException( "Could not transform the raw jdbc value", e );
		}
	}

}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Read the caused-by exception first: ORA-17008 ClosedConnection means the struct was materialized after the connection closed - access struct attributes eagerly inside the transaction.
  2. Set the session/JVM timezone explicitly (e.g. -Duser.timezone=... and -Doracle.jdbc.timezoneAsRegion=false) to fix timezone-based conversion failures.
  3. Use an Oracle JDBC driver version matching the database release.
  4. As a workaround, map the timestamp-with-timezone attribute as String inside the embeddable to bypass the oracle.sql conversion.

Example fix

// before: struct attribute touched after session closed -> connection passed to
// TIMESTAMPTZ.offsetDateTimeValue(connection) is already closed
List<Order> orders = tx.inTx(s -> s.createQuery(...).getResultList());
orders.get(0).getDetails().getCreatedAt();   // lazy, session gone
// after: force materialization inside the transaction
List<Order> orders = tx.inTx(s -> {
    List<Order> l = s.createQuery(...).getResultList();
    l.forEach(o -> o.getDetails().getCreatedAt()); // read while connection live
    return l;
});
Defensive patterns

Strategy: try-catch

Try / catch

catch (HibernateException e) {
    if ("Could not transform the raw jdbc value".equals(e.getMessage())) {
        Throwable root = e.getCause();
        // root is usually ClosedConnectionException (read after close) or a timezone error
        log.error("Oracle struct read failed: {}", root, e);
        throw new DataAccessException("re-run the query with the session open", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Selecting an entity mapped to an Oracle object type via OracleReflectionStructJdbcType whose attributes include TIMESTAMPTZ/TIMESTAMPLTZ/INTERVAL oracle.sql types, where the reflective conversion throws: the physical connection was closed before the struct was read (detached lazy access, pool eviction), the JDBC session timezone is invalid, or the ojdbc jar does not match the database.

Common situations: Lazy-loading struct-typed attributes after the session/connection closed; Oracle timestamps with time zone (TIMESTAMPTZ) read under a JVM/DB timezone mismatch ('oracle.jdbc.timezoneAsRegion' issues); mixing ojdbc versions with Oracle RAC/ASM upgrades.

Related errors


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