5

私は Grails サービス クラスで条件クエリを作成しました。そこでは、熱心な結合が実行されることを期待し、JSON 応答または GSP で結果を表示するときに子オブジェクトの遅延読み込みを回避します。クエリは期待どおりに実行されました (DataSource.groovy で hibernate.show_sql=true を設定するとクエリが表示されます) が、GSP で関連付けをクロールすると、Hibernate が後続のクエリを遅延読み込みのように実行していることがわかります協会。熱心な読み込みが実際に機能しているとは確信していません。これらの関連付けのドメイン クラス内で lazy:false を設定したくありません。

これは条件クエリです。

def market = Market.withCriteria(uniqueResult:true){
    idEq(marketId)
    fetchMode 'resourceAssignments', FetchMode.JOIN
    fetchMode 'resourceAssignments.userRole', FetchMode.JOIN
    fetchMode 'resourceAssignments.userRole.role', FetchMode.JOIN
    fetchMode 'resourceAssignments.userRole.user', FetchMode.JOIN
    resourceAssignments{
        userRole{
            role{
                'in'('name', roleNames)
            }
        }
    }           
}

上記のクエリは問題なく返されます。ただし、私の GSP で次のコードを実行しようとすると、resourceAssignments を遅延フェッチしているかのように、Hibernate が 2 番目のクエリを発行していることがわかります。

<g:each in="${market.resourceAssignments}" var="ra">
</g:each>

空の WebRequestInterceptor を作成し、resources.groovy で openSessionInViewInterceptor を設定してそれを使用することで、OpenSessionInViewInterceptor を No-Op インターセプターでオーバーライドしようとさえしました。これを行うと、org.hibernate.LazyInitializationException を取得します。これは、私が考えていたことを確認しているようです。これらの関連付けを熱心にフェッチすることを指定した場合でも、Hibernate または GORM はまだ 2 番目のクエリを実行しようとしています。

4

1 に答える 1

6

基準クエリに関する Grails のバグのようです。ただし、機能するHQLクエリは次のとおりです。

def market = Market.executeQuery(
    'select m from Market m ' +
    'inner join fetch m.resourceAssignments as ra ' +
    'inner join fetch ra.userRole as ur ' +
    'inner join fetch ur.role as role ' +
    'inner join fetch ur.user as user ' +
    'where m.id=:marketId and role.name in (:roleNames)',
    [marketId: marketId, roleNames: roleNames], [max: 1])[0]
于 2013-02-08T21:04:48.647 に答える