Skip to content

Hibernate 7: a subquery projecting a path through an association correlates with a top-level association block of createCriteria #16762

Open

Description

@gustavoharff

Expected Behavior

A subquery takes a path such as owner.firstName from its own root, whatever association blocks the outer query has:

Pet.createCriteria().list {
    owner {
        eq('firstName', 'Homer')
    }
    'in'('name', new DetachedCriteria(Pet).build {
        projections {
            property('owner.firstName')
        }
    })
}

should select the pets of Homer whose name is the first name of the owner of any pet.

Actual Behaviour

The subquery takes owner from the outer query and comes out correlated:

... from pet p1_0 join person o1_0 on o1_0.id=p1_0.owner_id
where o1_0.first_name=?
  and p1_0.name in ((select o3_0.first_name from pet p2_0, person o3_0 where o3_0.id=p1_0.owner_id))

so it only matches pets named after their own owner, and the result depends on whether the owner { ... } block comes before or after the subquery.

The same query built with new DetachedCriteria(Pet).build { ... }, and a subquery inside a nested block, are not affected (covered by #16559).

Cause

In the createCriteria builder every association block records a join type (CriteriaMethodInvoker calls hibernateQuery.join(name, joinType), INNER when none is given), and JpaCriteriaQueryCreator.registerDetachedJoins turns each recorded join type into an alias definition named after the path. A subquery context looks these up through its parent: ExpressionResolver sees owner as a defined alias (AliasRegistry.isDefined / getDefinition walk the parent registries) and then takes the outer join from the parent JoinTracker.

A join type recorded for an association block is not an alias the user named, so it should not be visible to a subquery; only explicit aliases (createAlias, as) should correlate.

Steps To Reproduce

Run the query above on Hibernate 7 with a Pet that has an owner (Person) and a pet named after the first name of another pet's owner.

Environment Information

Example Application

The query above, in the style of HibernateCriteriaBuilderNestedJoinTypeSpec in grails-data-hibernate7/core.

Version

8.0.x

Activity

  1. added 2 commits that reference this issue on Oct 27, 2026
    54b1adf
    72b1041
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions