私が取り組んでいるプロジェクトには、あるコード ブランチと別のコード ブランチでは動的ファインダーの動作が異なるコードがいくつかあります。
このコード行は、所属しているブランチに関係なく、すべての広告主 (8 件あります) を返します。
Advertiser.findAllByOwner(ownerInstance)
しかし、条件を追加し始めると、事態は奇妙になります。ブランチ A で、次のコードはすべての広告主を返します。
Advertiser.findAllByOwner(ownerInstance, [max: 25])
しかし、ブランチ B では、そのコードは 1 つの広告主のみを返します。
アプリケーション コードの変更が動的ファインダーの動作に影響を与える可能性はないようです。私が間違っている?これが機能しない原因となるものは他にありますか?
編集
クラス定義を投稿するように依頼されました。すべてを投稿する代わりに、私が重要だと思う部分を投稿します。
static mapping = {
owner fetch: 'join'
category fetch: 'join'
subcategory fetch: 'join'
}
static fetchMode = [
grades: 'eager',
advertiserKeywords: 'eager',
advertiserConnections: 'eager'
]
このコードはブランチ B にはありましたが、ブランチ A にはありませんでした。引き出すと、期待どおりに機能するようになりました。
このコードをさらに掘り下げて、何が観察できるかを確認することにしました。withCriteria
動的ファインダーの代わりに使用すると、興味深いことがわかりました。
Advertiser.withCriteria{owner{idEq(ownerInstance.id)}}
私が見つけたのは、これが何千もの重複を返したことです! だから私は使ってみましたlistDistinct
:
Adviertiser.createCriteria().listDistinct{owner{idEq(ownerInstance.id)}}
これで、8 つの広告主すべてが重複なしで返されます。しかし、結果を制限しようとするとどうなりますか?
Advertiser.createCriteria().listDistinct{
owner{idEq(ownerInstance.id)}
maxResults 25
}
これで、動的ファインダーと同じように、単一の結果が返されます。maxResults
100K までクランクアップすると、8 つの結果すべてが得られます。
それで、何が起こっているのですか?結合または熱心なフェッチ (またはその両方) により、何千もの重複を返す SQL が生成されたようです。Grails の動的ファインダーは、デフォルトで個別の結果を返さなければならないので、それらを制限していないときは、何もおかしなことには気付きませんでした。しかし、制限を設定すると、レコードは ID 順に並べられているため、最初の 25 レコードはすべて重複レコードになり、1 つの異なるレコードのみが返されます。
結合と熱心なフェッチについては、そのコードが解決しようとしていた問題が何であるかがわからないため、それが必要かどうかはわかりません。問題は、このコードをクラスに含めると、なぜ多くの重複が生成されるのかということです。