hibernate/hibernate-orm · error · UnsupportedOperationException

Enum literal cannot be cast to BigDecimal

Error message

Enum literal cannot be cast to BigDecimal

What it means

Thrown by SqmEnumLiteral.asBigDecimal(). In Hibernate's SQM (semantic query model) tree, an enum literal can be converted to Integer/Long/Float/Double (through the enum's ordinal) or to String (through its name), but conversion to BigDecimal is deliberately not implemented because an enum constant has no decimal value, so the override always throws UnsupportedOperationException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmEnumLiteral.java:166

		return nodeBuilder().literal( ordinalValue() );
	}

	@Nonnull
	@Override
	public SqmExpression<Float> asFloat() {
		return nodeBuilder().literal( ordinalValue().floatValue() );
	}

	@Nonnull
	@Override
	public SqmExpression<Double> asDouble() {
		return nodeBuilder().literal( ordinalValue().doubleValue() );
	}

	@Nonnull
	@Override
	public SqmExpression<BigDecimal> asBigDecimal() {
		throw new UnsupportedOperationException( "Enum literal cannot be cast to BigDecimal" );
	}

	@Nonnull
	@Override
	public SqmExpression<BigInteger> asBigInteger() {
		throw new UnsupportedOperationException( "Enum literal cannot be cast to BigInteger" );
	}

	@Nonnull
	@Override
	public SqmExpression<String> asString() {
		return nodeBuilder().literal( getExpressibleJavaType().toName( getEnumValue() ) );
	}

	@Override
	public <X> X accept(SemanticQueryWalker<X> walker) {
		return walker.visitEnumLiteral( this );
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Convert through a supported type first: call asInteger() (ordinal) or asString() (name), then cast - e.g. asInteger().cast(BigDecimal.class).
  2. Compare against the enum's ordinal or name instead of coercing the enum literal to BigDecimal.
  3. If the enum encodes a decimal magnitude, map the attribute with an AttributeConverter to BigDecimal and query that representation instead of the enum literal.
  4. In generic coercion code, skip asBigDecimal() when the expression is an SqmEnumLiteral (instanceof check).

Example fix

// before
SqmExpression<BigDecimal> v = enumLiteralExpr.asBigDecimal(); // UnsupportedOperationException

// after - go via the ordinal, then cast
SqmExpression<BigDecimal> v = enumLiteralExpr.asInteger().cast( BigDecimal.class );
Defensive patterns

Strategy: type-guard

Type guard

static boolean isEnumLiteral(SqmExpression<?> e) {
    return e instanceof org.hibernate.query.sqm.tree.spi.expression.SqmEnumLiteral;
}

Try / catch

try {
    return expr.asBigDecimal();
} catch (UnsupportedOperationException e) {
    // enum literal: fall back to an ordinal-based cast
    return expr.asInteger().cast( BigDecimal.class );
}

Prevention

When it happens

Trigger: Calling asBigDecimal() on an expression Hibernate resolved to an SqmEnumLiteral: criteria code like builder.literal(MyEnum.ACTIVE).asBigDecimal(), generic numeric-coercion helpers that call asBigDecimal()/asBigInteger() on every SqmExpression, or queries that force an enum literal into a BigDecimal-typed position (comparing or casting it against a BigDecimal operand).

Common situations: Dynamic query builders that apply numeric coercion uniformly to all operands; arithmetic between an enum attribute and BigDecimal values; refactors where a formerly numeric column became an enum; porting queries from a dialect where implicit enum-to-number casts worked.

Related errors


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