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 中运行以下代码时,我可以看到 Hibernate 正在发出第二个查询,就好像它在懒惰地获取资源分配一样:

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

我什至尝试使用 No-Op 拦截器覆盖 OpenSessionInViewInterceptor,方法是创建一个空的 WebRequestInterceptor 并在 resources.groovy 中设置 openSessionInViewInterceptor 以使用它。一旦我这样做了,我就会得到一个 org.hibernate.LazyInitializationException,它似乎验证了我的想法——即使我已经指定我想要急切地获取这些关联,Hibernate 或 GORM 仍在尝试执行第二个查询。

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 回答