hibernate/hibernate-orm · error · UnsupportedOperationException

Unsupported specification: {specification}

Error message

Unsupported specification: {specification}

What it means

SQLiteDialect.trimPattern throws UnsupportedOperationException when asked for the SQL pattern of a TRIM specification it does not map. The method switches over the three TrimSpec constants BOTH, LEADING and TRAILING (each with a whitespace-only shortcut); the trailing throw is a defensive guard that is effectively unreachable through normal Hibernate use because the TrimSpec enum defines exactly those three values. It can only fire from custom code that calls trimPattern directly, or from a version mismatch where a newer hibernate-orm introduces a TrimSpec constant this community-dialects release does not know.

Source

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

	}

	@Override
	public String trimPattern(TrimSpec specification, boolean isWhitespace) {
		switch ( specification ) {
			case BOTH:
				return isWhitespace
						? "trim(?1)"
						: "trim(?1,?2)";
			case LEADING:
				return isWhitespace
						? "ltrim(?1)"
						: "ltrim(?1,?2)";
			case TRAILING:
				return isWhitespace
						? "rtrim(?1)"
						: "rtrim(?1,?2)";
		}
		throw new UnsupportedOperationException( "Unsupported specification: " + specification );
	}

	protected boolean supportsMathFunctions() {
		// Math functions have to be enabled through a compile time option: https://www.sqlite.org/lang_mathfunc.html
		return true;
	}

	@Override
	public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
		super.contributeTypes( typeContributions, serviceRegistry );
		final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration()
				.getJdbcTypeRegistry();
		jdbcTypeRegistry.addDescriptor( Types.BLOB, BlobJdbcType.PRIMITIVE_ARRAY_BINDING );
		jdbcTypeRegistry.addDescriptor( Types.CLOB, ClobJdbcType.STRING_BINDING );
	}

	@Override
	public LimitHandler getLimitHandler() {

View on GitHub (pinned to fad1729dce)

Solutions

  1. If calling trimPattern directly, pass only TrimSpec.BOTH, TrimSpec.LEADING or TrimSpec.TRAILING
  2. Align hibernate-community-dialects with the exact hibernate-orm version (use the hibernate-platform BOM) so no unknown TrimSpec exists
  3. In a custom dialect subclass, override trimPattern to handle the extra constant instead of throwing

Example fix

// before - custom dialect helper passes a computed spec
String pattern = dialect.trimPattern(spec, false);

// after - guard first
if (spec != TrimSpec.BOTH && spec != TrimSpec.LEADING && spec != TrimSpec.TRAILING) {
    throw new IllegalArgumentException('Unsupported trim spec: ' + spec);
}
String pattern = dialect.trimPattern(spec, false);
Defensive patterns

Strategy: type-guard

Type guard

static boolean isSupportedTrimSpec(TrimSpec spec) {
    return spec == TrimSpec.BOTH || spec == TrimSpec.LEADING || spec == TrimSpec.TRAILING;
}

Prevention

When it happens

Trigger: Directly calling dialect.trimPattern(spec, isWhitespace) with a value outside BOTH/LEADING/TRAILING from a custom Dialect or FunctionContributor; upgrading hibernate-orm ahead of hibernate-community-dialects so an unknown TrimSpec constant flows through.

Common situations: Dependency drift between hibernate-orm and hibernate-community-dialects (not using the hibernate-platform BOM); copy-pasting trimPattern into a custom SQLite subclass; dialect unit tests that pass mocked/extended enum values.

Related errors


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