hibernate/hibernate-orm · error · IllegalArgumentException

TypedParameterValue has no type

Error message

TypedParameterValue has no type

What it means

Thrown by setParameter(Parameter<P>, P value) when value is a TypedParameterValue whose type() returns null. TypedParameterValue pairs a value with its Hibernate Type for explicit bind typing; when constructed as new TypedParameterValue<>(null, v) the pair carries no type information, and Hibernate refuses to bind it rather than guessing.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/AbstractCommonQueryContract.java:1285

	@Nonnull
	public <P> CommonQueryContractImplementor setParameter(
			@Nonnull QueryParameter<P> parameter,
			@Nullable P value,
			@Nonnull Type<P> type) {
		locateBinding( parameter ).setBindValue( value, (BindableType<P>) type );
		return this;
	}

	@Override
	@Nonnull
	public <P> CommonQueryContractImplementor setParameter(
			@Nonnull Parameter<P> parameter,
			@Nullable P value) {
		if ( value instanceof TypedParameterValue<?> typedParameterValue ) {
			final var parameterType = parameter.getParameterType();
			final var type = typedParameterValue.type();
			if ( type == null ) {
				throw new IllegalArgumentException( "TypedParameterValue has no type" );
			}
			if ( !parameterType.isAssignableFrom( type.getJavaType() ) ) {
				throw new QueryArgumentException( "Given TypedParameterValue is not assignable to given Parameter type",
						parameterType, typedParameterValue.value() );
			}
			@SuppressWarnings("unchecked") // safe, because we just checked
			final var typedValue = (TypedParameterValue<P>) value;
			final var castValue = typedValue.value();
			final var castType = typedValue.type();
			if ( parameter instanceof QueryParameter<P> queryParameter ) {
				setParameter( queryParameter, castValue, castType );
			}
			else {
				locateBinding( parameter ).setBindValue( castValue, castType );
			}
		}
		else {
			locateBinding( parameter ).setBindValue( value, resolveJdbcParameterTypeIfNecessary() );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Always supply a type: new TypedParameterValue<>(StandardBasicTypes.STRING, "abc") or a JavaType/BasicTypeReference
  2. If you don't need explicit typing, pass the raw value instead of a TypedParameterValue
  3. Centralize TypedParameterValue construction in one factory method that throws a clear error if the type argument is null

Example fix

// before
query.setParameter( param, new TypedParameterValue<>( null, 42 ) );

// after
query.setParameter( param, new TypedParameterValue<>( StandardBasicTypes.INTEGER, 42 ) );
// or simply the raw value:
query.setParameter( param, 42 );
Defensive patterns

Strategy: type-guard

Validate before calling

TypedParameterValue<?> tpv = (TypedParameterValue<?>) value;
if ( tpv.type() == null ) throw new IllegalArgumentException( "TypedParameterValue needs a type" );
query.setParameter( param, tpv );

Type guard

static boolean isFullyTyped(TypedParameterValue<?> v) {
    return v != null && v.type() != null;
}

Prevention

When it happens

Trigger: new TypedParameterValue<>(null, "abc") passed to query.setParameter(param, typedValue). A factory/mapper building TypedParameterValue with an Optional<Type> that is empty; copy-paste from setParameter(name, value) paths where the untyped overload is legal (plain values don't need a type).

Common situations: Code intended for setParameter(String,Object) — which handles raw values — refactored onto the Parameter-typed overload; conditional typing logic ('use Long type only for longs, else null') leaving null in the non-long branch.

Related errors


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