hibernate/hibernate-orm · error · IllegalArgumentException

Configuration property hibernate.jdbc.time_zone value [{}] i

Error message

Configuration property hibernate.jdbc.time_zone value [{}] is not supported

What it means

The hibernate.jdbc.time_zone setting accepts only a java.util.TimeZone, a java.time.ZoneId, a String parseable by ZoneId.of (e.g. 'UTC', 'Europe/Berlin', 'GMT+2'), or nothing at all. SessionFactoryOptionsBuilder.getJdbcTimeZone throws IllegalArgumentException for any other non-null value type, failing SessionFactory bootstrap. Note: a String that is not a valid zone id throws ZoneRulesException instead — this error is specifically about the value's type.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java:630

		}
		catch (Exception e) {
			throw new RuntimeException( "Unable to instantiate StatementObserver - " + setting, e );
		}
	}

	@Nullable
	private TimeZone getJdbcTimeZone(Object jdbcTimeZoneValue) {
		if ( jdbcTimeZoneValue instanceof TimeZone timeZone ) {
			return timeZone;
		}
		else if ( jdbcTimeZoneValue instanceof ZoneId zoneId ) {
			return TimeZone.getTimeZone( zoneId );
		}
		else if ( jdbcTimeZoneValue instanceof String string ) {
			return TimeZone.getTimeZone( ZoneId.of( string ) );
		}
		else if ( jdbcTimeZoneValue != null ) {
			throw new IllegalArgumentException( "Configuration property " + JDBC_TIME_ZONE
												+ " value [" + jdbcTimeZoneValue + "] is not supported" );
		}
		else {
			return null;
		}
	}

	@Nonnull
	private Nulls getDefaultNullPrecedence(Object defaultNullPrecedence) {
		if ( defaultNullPrecedence instanceof Nulls jpaValue ) {
			return jpaValue;
		}
		else if ( defaultNullPrecedence instanceof String string ) {
			final var parsed = NullsHelper.parse( string );
			if ( parsed == null ) {
				throw new IllegalArgumentException( "Configuration property " + DEFAULT_NULL_ORDERING
													+ " value '" + defaultNullPrecedence + "' is not recognized" );
			}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use a java.time.ZoneId or java.util.TimeZone instance: props.put(JdbcSettings.JDBC_TIME_ZONE, ZoneId.of("UTC"))
  2. Or use a valid ZoneId string: 'UTC', 'Europe/Berlin', or offset form 'GMT+02:00'
  3. Convert numeric offsets to a zone string before setting (e.g. String.format("GMT%+02d:00", offset))
  4. Leave the property unset to use the JVM default

Example fix

// before:
props.put("hibernate.jdbc.time_zone", 2); // Integer -> IllegalArgumentException

// after:
props.put("hibernate.jdbc.time_zone", ZoneId.of("GMT+02:00")); // or the String "GMT+02:00"
Defensive patterns

Strategy: validation

Validate before calling

// normalize the value to a supported type before passing it to Hibernate
static Object normalizeJdbcTimeZone(Object raw) {
    if (raw == null || raw instanceof TimeZone || raw instanceof ZoneId) return raw;
    if (raw instanceof String s) return ZoneId.of(s.trim()); // throws early with a clear ZoneId error
    if (raw instanceof Integer offset) return ZoneId.of(String.format("GMT%+03d:00", offset));
    throw new IllegalArgumentException("Unsupported jdbc time zone value type: " + raw.getClass());
}

props.put(JdbcSettings.JDBC_TIME_ZONE, normalizeJdbcTimeZone(rawValue));

Type guard

static boolean isSupportedTimeZoneValue(Object v) {
    return v == null || v instanceof java.util.TimeZone
        || v instanceof java.time.ZoneId || v instanceof String;
}

Try / catch

try {
    sessionFactory = configuration.buildSessionFactory();
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("hibernate.jdbc.time_zone")) {
        props.put("hibernate.jdbc.time_zone", ZoneId.systemDefault().getId()); // safe value, rebuild
    } else throw e;
}

Prevention

When it happens

Trigger: Passing hibernate.jdbc.time_zone as an Integer/Long offset (e.g. 2), a boolean, an org.joda.time.DateTimeZone, or any custom object — anything that is not TimeZone, ZoneId, or String.

Common situations: Reading the offset from an environment variable into a numeric type and putting it into properties directly; migrating code that used a Joda-Time zone; Spring's environment binding coercing the value to a non-string type; passing a Calendar.

Related errors


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