Copilot commented on code in PR #16820:
URL: https://github.com/apache/grails-core/pull/16820#discussion_r4436631073


##########
grails-datamapping-core/src/main/groovy/grails/gorm/DetachedCriteria.groovy:
##########
@@ -739,7 +742,7 @@ class DetachedCriteria<T> extends 
AbstractDetachedCriteria<T> implements GormOpe
 
         GormStaticApi staticApi = 
GormRegistry.instance.findStaticApi(targetClass, connectionName)
         staticApi.withDatastoreSession { Session session ->
-            applyLazyCriteria()
+            DetachedCriteria<T> effective = materializeLazyCriteria()
             Query query
             if (alias && (session instanceof QueryAliasAwareSession)) {
                 query = session.createQuery(targetClass, alias)

Review Comment:
   A deferred closure can set the root alias, but query creation still reads 
`alias` from the original rather than `effective`. This loses the deferred 
alias and breaks alias-qualified restrictions on alias-aware backends such as 
Hibernate 5. Use `effective.alias` for both the alias check and the 
`session.createQuery()` argument.



##########
grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/query/criteria/AbstractDetachedCriteria.groovy:
##########
@@ -1118,6 +1124,22 @@ abstract class AbstractDetachedCriteria<T> implements 
Criteria, Cloneable {
         this.with(criteria)
     }
 
+    /**
+     * Returns this criteria with its deferred query applied, without mutating 
it: the original keeps the
+     * deferred query, so a criteria shared between threads materializes a 
copy each time and no deferred
+     * definition is applied twice.
+     */
+    AbstractDetachedCriteria<T> materializeLazyCriteria() {
+        Closure pending = lazyQuery
+        if (pending == null) {
+            return this
+        }
+        AbstractDetachedCriteria<T> materialized = clone()

Review Comment:
   `clone()` copies the list and map containers but still shares their existing 
`DetachedAssociationCriteria` nodes. A deferred `createAlias()` for an existing 
association therefore changes the original node's alias, and chaining 
`.eq(...)` appends restrictions to that shared node on every materialization, 
including across threads. Copy the mutable association nodes before applying 
the closure, preserving their metadata and matching references in the criterion 
tree and association map.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to