hibernate/hibernate-orm · error · UnsupportedOperationException

Unsupported unit: {unit}

Error message

Unsupported unit: {unit}

What it means

translateExtractField() is the generic fallback for rendering extract(), but the SQLite dialect implements every unit directly in extractPattern() with strftime-based templates. This override exists purely to fail fast: the source comment states all units are handled in extractPattern so the method should never be hit. Reaching it signals a mismatch between the dialect and the hibernate-orm version in use, or a custom code path that bypasses the dialect's extract patterns.

Source

Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLiteDialect.java:651

				.replace("m", "%M") //?????

				//second
				.replace("ss", "%S")
				.replace("s", "%S") //?????

				//fractional seconds
				.replace("SSSSSS", "%f") //5 is the max
				.replace("SSSSS", "%f")
				.replace("SSSS", "%f")
				.replace("SSS", "%f")
				.replace("SS", "%f")
				.replace("S", "%f");
	}

	@Override
	public String translateExtractField(TemporalUnit unit) {
		// All units should be handled in extractPattern so we should never hit this method
		throw new UnsupportedOperationException( "Unsupported unit: " + unit );
	}

	@Override
	public void appendDateTimeLiteral(
			SqlAppender appender,
			TemporalAccessor temporalAccessor,
			TemporalType precision,
			TimeZone jdbcTimeZone) {
		switch ( precision ) {
			case DATE:
				appender.appendSql( "date(" );
				appendAsDate( appender, temporalAccessor );
				appender.appendSql( ')' );
				break;
			case TIME:
				appender.appendSql( "time(" );
				appendAsTime( appender, temporalAccessor, supportsTemporalLiteralOffset(), jdbcTimeZone );
				appender.appendSql( ')' );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Align hibernate-orm and hibernate-community-dialects to the same release family, preferably via the hibernate-platform BOM
  2. Verify with a dependency tree that only one hibernate-core version is on the classpath
  3. In a custom SQLite dialect, override extractPattern() so every TemporalUnit you use returns a strftime pattern instead of falling through to the generic path

Example fix

// before - custom dialect lets unknown units fall through to the generic path
@Override
public String extractPattern(TemporalUnit unit) {
    return super.extractPattern(unit);
}

// after - map the units you actually use
@Override
public String extractPattern(TemporalUnit unit) {
    return switch (unit) {
        case QUARTER -> 'cast(strftime(''%m'',?2) as integer)/3+1';
        default -> super.extractPattern(unit);
    };
}
Defensive patterns

Strategy: validation

Validate before calling

String orm = org.hibernate.Version.getVersionString();
String dialects = SQLiteDialect.class.getPackage().getImplementationVersion();
if (dialects != null && !orm.startsWith(dialects.substring(0, dialects.lastIndexOf('.')))) {
    throw new IllegalStateException(
        'hibernate-orm ' + orm + ' and hibernate-community-dialects ' + dialects
        + ' are from different release trains; align them');
}

Prevention

When it happens

Trigger: Running hibernate-community-dialects against a different hibernate-orm version than it was built for (mixing ORM jars and dialect jars from different release trains); custom functions or a dialect subclass that route extract() through the generic translation path instead of the dialect's patterns.

Common situations: Dependency drift: hibernate-orm upgraded by a BOM while hibernate-community-dialects lagged behind (or vice versa); multiple hibernate-core versions on the classpath after merging dependencies; a custom SQLite subclass overriding extractPattern() and falling back to super for unhandled units.

Related errors


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