hibernate/hibernate-orm · error · FunctionArgumentException

Step parameter of function '%s()' is of type '%s', but must

Error message

Step parameter of function '%s()' is of type '%s', but must be of type interval

What it means

For temporal generate_series(start, stop, step) the step must be an interval/duration type (e.g. Hibernate's DurationJavaType / interval literal). Passing a number, string, or timestamp as step throws this FunctionArgumentException naming the actual step type.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/GenerateSeriesArgumentValidator.java:100

			}
		}
		else if ( jdbcType.isTemporal() ) {
			if ( step == null ) {
				throw new FunctionArgumentException(
						String.format(
								Locale.ROOT,
								"Function %s() requires exactly 3 arguments when invoked with a temporal argument, but %d arguments given",
								functionName,
								arguments.size()
						)
				);
			}
			if ( stepType == null ) {
				throw unknownType( functionName, arguments, 2 );
			}
			final var stepJdbcType = ((JdbcMapping) stepType).getJdbcType();
			if ( !stepJdbcType.isInterval() && !stepJdbcType.isDuration() ) {
				throw new FunctionArgumentException(
						String.format(
								"Step parameter of function '%s()' is of type '%s', but must be of type interval",
								functionName,
								stepType.getTypeName()
						)
				);
			}
		}
		else {
			throw new FunctionArgumentException(
					String.format(
							"Unsupported type '%s' for function '%s()'. Only integral, decimal and timestamp types are supported.",
							startType.getTypeName(),
							functionName
					)
			);
		}
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use an interval-typed step: by hours(1), or bind a java.time.Duration parameter so the domain type is a duration
  2. Convert numeric steps: multiply inside the query using duration arithmetic or precompute a Duration in Java
  3. Avoid raw string intervals; HQL needs the interval literal/typed parameter, not '1 hour'::interval text

Example fix

// before
session.createQuery("select gs from generate_series(:f, :t, :step) gs")
        .setParameter("step", 60); // Integer step -> error

// after
session.createQuery("select gs from generate_series(:f, :t, :step) gs")
        .setParameter("step", Duration.ofMinutes(1)); // duration type
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(step instanceof java.time.Duration) && isTemporal(start)) {
    throw new IllegalArgumentException("Temporal series step must be a Duration, got " + step.getClass());
}

Type guard

boolean isIntervalStep(Object step) { return step instanceof Duration; }

Prevention

When it happens

Trigger: generate_series(ts1, ts2, 1), generate_series(:f, :t, :minutes) where :minutes is bound as Integer/String, or copied PostgreSQL SQL where the step is an untyped string '1 hour' that HQL parses as String.

Common situations: Porting PostgreSQL generate_series(timestamp, timestamp, interval) but binding the step as an int of seconds or a String; criteria builders supplying a Duration as long milliseconds.

Related errors


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