hibernate/hibernate-orm · error · IllegalArgumentException
Couldn't determine basic type for java type: {}
Error message
Couldn't determine basic type for java type: {} What it means
While building the path source for a navigable function result, SqmFunctionPath.determinePathSource looks up the function's return Java type in the JpaMetamodel (managed types) and then in the basic-type registry. If neither knows the Java type, no SqmPathSource can be constructed and IllegalArgumentException is thrown naming the class. This means the function returns a Java type for which no basic/mapped type is registered.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmFunctionPath.java:64
this.function = function;
}
private static <X> SqmPathSource<X> determinePathSource(NavigablePath navigablePath, SqmFunction<?> function) {
//noinspection unchecked
final var nodeType = (SqmBindableType<X>) function.getNodeType();
if ( nodeType == null ) {
throw new IllegalArgumentException( "Null return type for function: " + function.getFunctionName() );
}
final var bindableJavaType = nodeType.getJavaType();
final var managedType =
function.nodeBuilder().getJpaMetamodel()
.findManagedType( bindableJavaType );
if ( managedType == null ) {
final var basicType =
function.nodeBuilder().getTypeConfiguration()
.getBasicTypeForJavaType( bindableJavaType );
if ( basicType == null ) {
throw new IllegalArgumentException( "Couldn't determine basic type for java type: " + bindableJavaType.getName() );
}
return new BasicSqmPathSource<>(
navigablePath.getFullPath(),
null,
basicType,
basicType.getRelationalJavaType(),
Bindable.BindableType.SINGULAR_ATTRIBUTE,
false
);
}
else if ( managedType.getPersistenceType() == Type.PersistenceType.EMBEDDABLE ) {
return new EmbeddedSqmPathSource<>(
navigablePath.getFullPath(),
null,
(SqmEmbeddableDomainType<X>) managedType,
Bindable.BindableType.SINGULAR_ATTRIBUTE,
false
);View on GitHub (pinned to fad1729dce)
Solutions
- Register a basic type / JavaTypeDescriptor for the return Java type (metadataBuilder.applyBasicType(...), @JavaTypeRegistration, or a TypeContributor) so getBasicTypeForJavaType(rt) resolves
- Change the function descriptor to declare a standard mapped return type (String, Integer, etc.)
- Wrap the call in cast(f(x) as ...) to force a concrete mapped type before navigating
- If the return type is actually a mapped embeddable/entity, make sure it is part of the persistence unit so findManagedType finds it
Example fix
// before: function returns Money, no type registered // HQL: select money_of(p).amount from Person p // -> "Couldn't determine basic type for java type: com.acme.Money" // after: register the type before building the SessionFactory StandardServiceRegistryBuilder builder = ...; MetadataBuilder mb = new MetadataBuilderImpl(builder.build())...; mb.applyBasicType(new MoneyType()); // Money <-> MoneyType mapping // or annotate the domain class: @JavaType(MoneyJavaTypeDescriptor.class)
Defensive patterns
Strategy: validation
Validate before calling
// verify the function's return Java type is known to the factory before navigating
Class<?> rt = function.getNodeType().getJavaType();
SessionFactoryImplementor sfi = emf.unwrap(SessionFactoryImplementor.class);
boolean known = sfi.getJpaMetamodel().findManagedType(rt) != null
|| sfi.getTypeConfiguration().getBasicTypeForJavaType(rt) != null;
if (!known) {
throw new IllegalStateException("No basic/managed type registered for " + rt.getName()
+ "; register it via metadataBuilder.applyBasicType or @JavaTypeRegistration");
} Try / catch
try {
path = new SqmFunctionPath<>(function).get(attr);
} catch (IllegalArgumentException e) {
// message names the unmapped Java type: add a BasicType/JavaTypeDescriptor registration
throw new IllegalStateException("Unmapped function return type; register a type mapping", e);
} Prevention
- Register BasicType/JavaTypeDescriptor mappings for custom value classes returned by functions
- Prefer standard Java types (String, BigDecimal, ...) as custom function return types
- Cover function-return types in mapping tests before using them in HQL navigation
- Keep @JavaTypeRegistration/@Type registrations alongside the domain model so types resolve globally
When it happens
Trigger: A custom function whose descriptor declares an exotic return Java type (custom value class, Object, Serializable, an unregistered record) with no BasicType/JavaTypeDescriptor registered; navigating attributes from such a function result: f(e.x).sub.
Common situations: Domain value objects (Money, Coordinate) used as function return types without a @Type/JavaTypeRegistration or BasicTypeContributor; upgrading Hibernate versions where lax type resolution was tightened; functions returning Object in utility libraries.
Related errors
- Function argument [%s] of type [%s] at specified position [%
- Null return type for function: {}
- Unsupported return type for function: {}
- Index access is only supported for basic plural types.
- Embeddable paths cannot be TREAT-ed
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/07d5183cbb4ddbd7.
Report an issue: GitHub.