hibernate/hibernate-orm · error · HibernateException

Unable to determine JDBC type for converted parameter relati

Error message

Unable to determine JDBC type for converted parameter relational type: " + relationalJavaType.getTypeName()

What it means

Thrown by ConverterHelper.createConvertedParameterType when building a BasicType for a query or procedure parameter that carries an explicit AttributeConverter. After constructing the JpaAttributeConverter, Hibernate looks up a standard basic type for the converter's relational (database-side) Java type; if none is registered, it cannot determine the JDBC type and fails.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/ConverterHelper.java:80

			Class<? extends AttributeConverter<X,Y>> converterClass,
			ServiceRegistry serviceRegistry,
			TypeConfiguration typeConfiguration) {
		var converterBean = serviceRegistry.requireService( ManagedBeanRegistry.class ).getBean( converterClass );
		return createJpaAttributeConverter( converterBean, typeConfiguration.getJavaTypeRegistry() );
	}

	public static <X> BasicType<X> createConvertedParameterType(
			Class<? extends AttributeConverter<X,?>> converterClass,
			ServiceRegistry serviceRegistry,
			TypeConfiguration typeConfiguration) {
		//noinspection unchecked,rawtypes
		final JpaAttributeConverter<X,Object> converter =
				createJpaAttributeConverter( (Class) converterClass, serviceRegistry, typeConfiguration );
		final var relationalJavaType = converter.getRelationalJavaType();
		final var relationalType =
				typeConfiguration.standardBasicTypeForJavaType( relationalJavaType.getJavaTypeClass() );
		if ( relationalType == null ) {
			throw new HibernateException(
					"Unable to determine JDBC type for converted parameter relational type: "
							+ relationalJavaType.getTypeName()
			);
		}
		return new ConvertedBasicTypeImpl<>(
				"converted-parameter::" + converter.getConverterJavaType().getTypeName(),
				String.format(
						"BasicType adapter for converted query parameter AttributeConverter<%s,%s>",
						converter.getDomainJavaType().getTypeName(),
						relationalJavaType.getTypeName()
				),
				relationalType.getJdbcType(),
				converter
		);
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Change the converter's relational type to a standard basic type (String, Integer, Long, UUID, ...)
  2. If a custom relational type is required, register a JavaType and JdbcType for it (TypeContributor / @JavaTypeRegistration + @JdbcTypeRegistration)
  3. Drop the converter argument from setParameter and convert the value manually before binding
  4. Check for typos in the converter class passed to the parameter API

Example fix

// before
public class TagConverter implements AttributeConverter<Tag, TagCode> { ... }
query.setParameter("tag", tag, TagConverter.class); // TagCode is not a basic type
// after
public class TagConverter implements AttributeConverter<Tag, String> { ... }
query.setParameter("tag", tag, TagConverter.class);
Defensive patterns

Strategy: validation

Validate before calling

// before binding a converter-typed parameter, assert the relational side is a basic type
TypeConfiguration tc = sessionFactory.getTypeConfiguration();
boolean ok = tc.standardBasicTypeForJavaType(TagCode.class) != null;
if (!ok) throw new IllegalArgumentException("Relational type of converter is not a basic type");

Type guard

static boolean converterHasBasicRelationalType(Class<? extends AttributeConverter<?, ?>> c) {
    Type t = c.getGenericInterfaces()[0]; // AttributeConverter<D,R>
    if (t instanceof ParameterizedType pt) {
        Class<?> r = (Class<?>) pt.getActualTypeArguments()[1];
        return Set.of(String.class, Integer.class, Long.class, Boolean.class,
                java.math.BigDecimal.class, java.util.UUID.class, java.time.LocalDate.class)
              .contains(r);
    }
    return false;
}

Try / catch

try {
    query.setParameter("tag", tag, TagConverter.class);
} catch (HibernateException e) {
    // message contains 'Unable to determine JDBC type for converted parameter relational type'
    throw new MappingException("Parameter converter " + TagConverter.class + " must target a basic relational type", e);
}

Prevention

When it happens

Trigger: Calling setParameter(name, value, MyConverter.class) on HQL/JPQL or native queries, criteriaBuilder.parameter(...) with a converter, or ProcedureCall parameter registration, where MyConverter's second type argument (the relational type) is not a known basic type (e.g. a custom class with no registered JavaType/JdbcType).

Common situations: Converter declared as AttributeConverter<Domain, CustomRelationalType> instead of AttributeConverter<Domain, String/Integer/...>; upgrading to Hibernate 6+ where the parameter-converter overload resolves types strictly; using a wrapper class (e.g. a record) as the relational side with no custom type registration.

Related errors


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