hibernate/hibernate-orm · error · IllegalArgumentException
Invalid path provided to 'fk()' function: {}
Error message
Invalid path provided to 'fk()' function: {} What it means
fk() is an HQL function that exposes the raw foreign-key column value(s) of a to-one association. SqmFkExpression.pathDomainType requires the path's referenced type to be an IdentifiableDomainType (i.e. the path navigates a @ManyToOne/@OneToOne to an entity); anything else (embeddable, basic attribute, or a plural attribute path) throws IllegalArgumentException naming the offending NavigablePath.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmFkExpression.java:53
NavigablePath navigablePath,
SqmPath<?> toOnePath) {
super(
navigablePath,
(SqmPathSource<T>)
castNonNull( pathDomainType( toOnePath )
.getIdentifierDescriptor() ),
toOnePath,
toOnePath.nodeBuilder()
);
}
private static IdentifiableDomainType<?> pathDomainType(SqmPath<?> toOnePath) {
if ( toOnePath.getReferencedPathSource().getPathType()
instanceof IdentifiableDomainType<?> identifiableDomainType ) {
return identifiableDomainType;
}
else {
throw new IllegalArgumentException( "Invalid path provided to 'fk()' function: "
+ toOnePath.getNavigablePath() );
}
}
@Override
public @Nonnull SqmPath<?> getLhs() {
return castNonNull( super.getLhs() );
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitFkExpression( this );
}
@Override
public void appendHqlString(StringBuilder hql, SqmRenderContext context) {
hql.append( "fk(" );
getLhs().appendHqlString( hql, context );View on GitHub (pinned to fad1729dce)
Solutions
- Apply fk() only to a to-one association attribute: fk(p.department) where 'department' is @ManyToOne or @OneToOne to an entity
- For embedded identifiers or embedded values, navigate the association or its parts directly (p.address.zipCode) instead of fk()
- If you need the target's identifier, use the association itself (p.department.id) which Hibernate optimizes to the FK column anyway
- Double-check the mapping of the attribute you pass to fk(): it must be entity-typed and singular
Example fix
// before: address is @Embedded in Person select p.id from Person p where fk(p.address) = :zip // after: department is @ManyToOne Department in Person select p.id from Person p where fk(p.department) = :deptId
Defensive patterns
Strategy: validation
Validate before calling
// only pass to-one, entity-typed paths to fk()
SqmPathSource<?> src = toOnePath.getReferencedPathSource();
if (!(src.getPathType() instanceof IdentifiableDomainType<?>)) {
throw new IllegalArgumentException(
"fk() requires a to-one association to an entity, got: "
+ toOnePath.getNavigablePath());
}
// safe: emf.getCriteriaBuilder()... query using fk(toOnePath) Type guard
static boolean isToOneEntityPath(SqmPath<?> path) {
SqmPathSource<?> src = path.getReferencedPathSource();
return src.getPathType() instanceof IdentifiableDomainType<?>
&& !(src.getSqmType() instanceof org.hibernate.metamodel.model.domain.PluralAttribute<?, ?, ?>);
} Try / catch
try {
return em.createQuery("select fk(p.department) from Person p where ...", Long.class);
} catch (IllegalArgumentException e) {
// message contains the offending NavigablePath: fix the path to a @ManyToOne/@OneToOne attribute
throw new IllegalArgumentException("fk() misuse in query: " + e.getMessage(), e);
} Prevention
- Reserve fk() for @ManyToOne/@OneToOne association paths only
- For embedded or basic values, navigate the attribute path directly instead of fk()
- Remember p.target.id is automatically optimized to the FK column - usually you do not need fk() at all
- When porting native SQL FK comparisons, double-check each fk() argument is an entity association
When it happens
Trigger: HQL such as 'where fk(p.owner) = :id' when p.owner is an @Embedded attribute, a basic column, or a @OneToMany/@ManyToMany collection; building the same construct through the criteria API; calling fk() on a composite/embedded FK instead of the association itself.
Common situations: Developers assuming fk() extracts any 'id-like' column; using fk() against embedded composite FKs; porting native-SQL correlated-subquery idioms that compare raw FK columns into HQL; entity graphs where the association was refactored into an embeddable.
Related errors
- Fk paths cannot be TREAT-ed
- Entity discriminator cannot be de-referenced
- Entity discriminator cannot be de-referenced
- Could not resolve attribute '%s' of '%s' due to the attribut
- The function {name} is not an aggregate function
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/0d357e3c404aadf4.
Report an issue: GitHub.