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)
+    }
 }

Reply via email to