hibernate/hibernate-orm · error · IllegalArgumentException

Couldn't determine types of arguments to function…

Error message

Couldn't determine types of arguments to function 'generate_series'

What it means

Hibernate's set-returning function support (6.5+/7.x) builds an AnonymousTupleType for generate_series from the SQM types of the start and stop arguments. resolveTupleType coalesces the two arguments' expressible types; if both come back null (no type information on either argument) the tuple type cannot be constructed and the query fails during interpretation with this IllegalArgumentException.

Solutions

  1. Give the parameters an explicit type at bind time: q.setParameter("start", 1, Integer.class), or cast in HQL: generate_series(cast(:start as integer), cast(:stop as integer))
  2. Use typed literals or cb.literal(...) in criteria queries instead of raw parameters
  3. Bind non-null numeric defaults instead of null bounds
  4. Upgrade to the latest 6.x/7.x patch release — generate_series type inference improved across versions

Example fix

// before
em.createQuery("select s from generate_series(:a, :b) s(serie, idx)", Object[].class)
  .setParameter("a", from)   // untyped Object binding
  .setParameter("b", to);

// after
em.createQuery("select s from generate_series(cast(:a as integer), cast(:b as integer)) s(serie, idx)", Object[].class)
  .setParameter("a", from)
  .setParameter("b", to);
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast before query creation: series bounds must be non-null, concretely typed numbers
static void checkSeriesBounds(Object start, Object stop) {
    if (!(start instanceof Number) || !(stop instanceof Number)) {
        throw new IllegalArgumentException(
            "generate_series bounds must be non-null Numbers, got: " + start + ", " + stop);
    }
}

Type guard

static boolean isTypedSeriesBound(Object v) {
    return v instanceof Integer || v instanceof Long
        || v instanceof java.math.BigInteger || v instanceof java.math.BigDecimal;
}

Try / catch

try {
    return em.createQuery(hql, Object[].class).getResultList();
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("generate_series")) {
        throw new QuerySetupException("generate_series arguments need explicit types; use cast(:a as integer)", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: HQL/criteria generate_series calls where neither bound argument carries a resolvable SQM type: generate_series(:start, :stop) with parameters registered as Object/untyped, null literals passed as bounds, or arithmetic over untyped parameters.

Common situations: Porting native PostgreSQL generate_series queries to HQL; dynamic query builders that bind parameters without an explicit type class; null-valued bounds during exploratory testing; older 6.x releases with weaker type inference for set-returning functions.

Related errors


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

Appendix: source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/GenerateSeriesSetReturningFunctionTypeResolver.java:54

	protected final String defaultIndexSelectionExpression;

	public GenerateSeriesSetReturningFunctionTypeResolver(@Nullable String defaultValueColumnName, String defaultIndexSelectionExpression) {
		this.defaultValueColumnName = defaultValueColumnName;
		this.defaultIndexSelectionExpression = defaultIndexSelectionExpression;
	}

	@Override
	public AnonymousTupleType<?> resolveTupleType(List<? extends SqmTypedNode<?>> arguments, TypeConfiguration typeConfiguration) {
		final SqmTypedNode<?> start = arguments.get( 0 );
		final SqmTypedNode<?> stop = arguments.get( 1 );
		final SqmExpressible<?> startExpressible = start.getExpressible();
		final SqmExpressible<?> stopExpressible = stop.getExpressible();
		final SqmDomainType<?> type = NullnessHelper.coalesce(
				startExpressible == null ? null : startExpressible.getSqmType(),
				stopExpressible == null ? null : stopExpressible.getSqmType()
		);
		if ( type == null ) {
			throw new IllegalArgumentException( "Couldn't determine types of arguments to function 'generate_series'" );
		}

		final SqmBindableType<?>[] componentTypes = new SqmBindableType<?>[]{ type, typeConfiguration.getBasicTypeForJavaType( Long.class ) };
		final String[] componentNames = new String[]{ CollectionPart.Nature.ELEMENT.getName(), CollectionPart.Nature.INDEX.getName() };
		return new AnonymousTupleType<>( componentTypes, componentNames );
	}

	@Override
	public SelectableMapping[] resolveFunctionReturnType(
			List<? extends SqlAstNode> arguments,
			String tableIdentifierVariable,
			boolean lateral,
			boolean withOrdinality,
			SqmToSqlAstConverter converter) {
		final Expression start = (Expression) arguments.get( 0 );
		final Expression stop = (Expression) arguments.get( 0 );
		final JdbcMappingContainer expressionType = NullnessHelper.coalesce(
				start.getExpressionType(),

View on GitHub (pinned to fad1729dce)