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

  1. Apply fk() only to a to-one association attribute: fk(p.department) where 'department' is @ManyToOne or @OneToOne to an entity
  2. For embedded identifiers or embedded values, navigate the association or its parts directly (p.address.zipCode) instead of fk()
  3. If you need the target's identifier, use the association itself (p.department.id) which Hibernate optimizes to the FK column anyway
  4. 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

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


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