hibernate/hibernate-orm · error · UnsupportedOperationException

Enum literal cannot be cast to BigInteger

Error message

Enum literal cannot be cast to BigInteger

What it means

Thrown by SqmEnumLiteral.asBigInteger(). The SQM enum literal supports asInteger/asLong/asFloat/asDouble (ordinal-based) and asString (name-based), but BigInteger conversion is not implemented because an enum constant has no integer magnitude beyond its ordinal, so the override unconditionally throws UnsupportedOperationException.

Source

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

		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 );
	}

	@Override
	public void appendHqlString(StringBuilder hql, SqmRenderContext context) {
		hql.append( getEnumValue().getDeclaringClass().getTypeName() );
		hql.append( '.' );
		hql.append( enumValueName );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Convert through a supported type first: asInteger() (ordinal) or asString() (name), then cast - e.g. asInteger().cast(BigInteger.class).
  2. Compare against the ordinal or name directly instead of coercing the literal.
  3. Store the numeric magnitude as a real attribute (or map via AttributeConverter to BigInteger) and query that instead of the enum literal.
  4. Branch in generic code: skip asBigInteger() when the expression is an SqmEnumLiteral.

Example fix

// before
SqmExpression<BigInteger> v = enumLiteralExpr.asBigInteger(); // UnsupportedOperationException

// after - via ordinal, then cast
SqmExpression<BigInteger> v = enumLiteralExpr.asInteger().cast( BigInteger.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.asBigInteger();
} catch (UnsupportedOperationException e) {
    // enum literal: fall back to an ordinal-based cast
    return expr.asInteger().cast( BigInteger.class );
}

Prevention

When it happens

Trigger: Calling asBigInteger() on an expression Hibernate resolved to an SqmEnumLiteral: criteria code like builder.literal(MyEnum.STATUS_A).asBigInteger(), generic coercion code that calls asBigInteger() on every expression node, or casting/forcing an enum literal into a BigInteger-typed comparison.

Common situations: Generic numeric-coercion utilities applied to all operands; ID/score values modeled as enums but used in BigInteger arithmetic; code migrated from hand-written SQL where the enum was stored as a number and compared to BigInteger parameters.

Related errors


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