This is an automated email from the ASF dual-hosted git repository. davydotcom pushed a commit to branch fix-detachedcriteria-join-get in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 03747c5f3e3b0805f18e709d9342dcb12e98856d Author: David Estes <[email protected]> AuthorDate: Wed Feb 25 17:49:57 2026 -0500 Fix DetachedCriteria join handling for get() in Hibernate DetachedCriteria joins with explicit join types were not updating HibernateQuery join state used by single-result execution. This caused get()/singleResult() paths to diverge from list() behavior for join fetch application.\n\nAdd an override of join(String, JoinType) in AbstractHibernateQuery that sets hasJoins, records joinTypes, and applies FetchMode.JOIN to criteria/detachedCriteria.\n\nAlso add a regression test in DetachedCriteriaJoinSpec proving Team.where { ... }.join('club'). [...] --- .../grails/orm/hibernate/query/AbstractHibernateQuery.java | 11 +++++++++++ .../grails/gorm/tests/DetachedCriteriaJoinSpec.groovy | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/query/AbstractHibernateQuery.java b/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/query/AbstractHibernateQuery.java index eed1e54bea..ef96b55d66 100644 --- a/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/query/AbstractHibernateQuery.java +++ b/grails-data-hibernate5/core/src/main/groovy/org/grails/orm/hibernate/query/AbstractHibernateQuery.java @@ -695,6 +695,17 @@ public abstract class AbstractHibernateQuery extends Query { return this; } + @Override + public Query join(String property, JoinType joinType) { + this.hasJoins = true; + this.joinTypes.put(property, joinType); + if (criteria != null) + criteria.setFetchMode(property, FetchMode.JOIN); + else if (detachedCriteria != null) + detachedCriteria.setFetchMode(property, FetchMode.JOIN); + return this; + } + @Override public Query select(String property) { this.hasJoins = true; diff --git a/grails-data-hibernate5/core/src/test/groovy/grails/gorm/tests/DetachedCriteriaJoinSpec.groovy b/grails-data-hibernate5/core/src/test/groovy/grails/gorm/tests/DetachedCriteriaJoinSpec.groovy index a1a38e064f..9863712502 100644 --- a/grails-data-hibernate5/core/src/test/groovy/grails/gorm/tests/DetachedCriteriaJoinSpec.groovy +++ b/grails-data-hibernate5/core/src/test/groovy/grails/gorm/tests/DetachedCriteriaJoinSpec.groovy @@ -23,6 +23,7 @@ import org.apache.grails.data.hibernate5.core.GrailsDataHibernate5TckManager import org.apache.grails.data.testing.tck.base.GrailsDataTckSpec import org.grails.datastore.gorm.finders.DynamicFinder import org.grails.orm.hibernate.query.HibernateQuery +import org.hibernate.Hibernate import jakarta.persistence.criteria.JoinType @@ -88,4 +89,17 @@ class DetachedCriteriaJoinSpec extends GrailsDataTckSpec<GrailsDataHibernate5Tck expect: joinType == org.hibernate.sql.JoinType.RIGHT_OUTER_JOIN } + + def 'check get honours join and eagerly loads association'() { + given: + def club = new Club(name: 'Juventus').save(flush: true) + new Team(name: 'Torino', club: club).save(flush: true) + + when: + Team team = Team.where { name == 'Torino' }.join('club').get() + + then: + team != null + Hibernate.isInitialized(team.club) + } }
