Skip to content

fix: copy missing fields in AbstractDetachedCriteria.clone()#15424

Merged
jamesfredley merged 1 commit into7.0.xfrom
fix/detached-criteria-clone
Feb 21, 2026
Merged

fix: copy missing fields in AbstractDetachedCriteria.clone()#15424
jamesfredley merged 1 commit into7.0.xfrom
fix/detached-criteria-clone

Conversation

@jamesfredley
Copy link
Contributor

Summary

  • AbstractDetachedCriteria.clone() was missing connectionName, lazyQuery, and associationCriteriaMap
  • This caused withConnection() settings to be silently lost when chained methods like max(), offset(), or sort() were called afterward, because each internally clones the criteria

Example of the bug

def criteria = Product.where { amount > 100 }
    .withConnection('secondary')
    .max(10)  // clones internally, loses connectionName

criteria.list()  // queries DEFAULT datasource instead of 'secondary'

Changes

  • AbstractDetachedCriteria.clone(): Added copying of connectionName, lazyQuery, and associationCriteriaMap (as a shallow copy)
  • DetachedCriteriaCloneSpec: 7 new unit tests verifying clone preserves all fields, creates independent map copies, and that withConnection().max() chaining works correctly

Test Results

  • DetachedCriteriaCloneSpec: 7/7 pass
  • codeStyle: pass

Fixes #15422

Reproducer: https://github.com/jamesfredley/grails-detachedcriteria-clone-connection

clone() was missing connectionName, lazyQuery, and
associationCriteriaMap. This caused withConnection() settings to be
lost when clone() was called by subsequent chained methods like max(),
offset(), or sort() - each of which internally clones the criteria.

Fixes #15422

Assisted-by: Claude Code <Claude@Claude.ai>
@github-actions github-actions bot added the bug label Feb 20, 2026
@jamesfredley jamesfredley self-assigned this Feb 20, 2026
@jamesfredley jamesfredley moved this to In Progress in Apache Grails Feb 20, 2026
@jamesfredley jamesfredley added this to the grails:7.0.8 milestone Feb 20, 2026
@jamesfredley jamesfredley marked this pull request as ready for review February 20, 2026 17:35
Copilot AI review requested due to automatic review settings February 20, 2026 17:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a critical bug in AbstractDetachedCriteria.clone() where three instance fields (connectionName, lazyQuery, and associationCriteriaMap) were not being copied during cloning. This caused withConnection() datasource routing settings to be silently lost when chained with other criteria methods like max(), offset(), or sort(), resulting in queries being executed against the wrong datasource.

Changes:

  • Added copying of connectionName, lazyQuery, and associationCriteriaMap fields in AbstractDetachedCriteria.clone()
  • Created comprehensive unit test suite with 7 tests verifying clone behavior for all newly copied fields

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/query/criteria/AbstractDetachedCriteria.groovy Added 3 lines to clone() method to copy connectionName, lazyQuery, and associationCriteriaMap fields
grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/query/criteria/DetachedCriteriaCloneSpec.groovy New test file with 7 unit tests verifying clone preserves all required fields and creates independent copies where needed

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jamesfredley jamesfredley merged commit 8395e3d into 7.0.x Feb 21, 2026
36 checks passed
@jamesfredley jamesfredley deleted the fix/detached-criteria-clone branch February 21, 2026 03:24
@github-project-automation github-project-automation bot moved this from In Progress to Done in Apache Grails Feb 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

AbstractDetachedCriteria.clone() does not copy connectionName, alias, lazyQuery, or associationCriteriaMap

3 participants