Grails GORM 条件左外连接

Grails GORM conditional left outer join

假设我有以下域 objects:

class Top {  
  User createdBy  
  Other other  
  static hasMany = [  
    children: Child,  
  ]  
}

class Child {
  User createdBy
  static belongsTo = [
    top: Top,
  ]
}

并且给定用户 myUser 和其他 myOther,我想要 select 所有顶部

top.other.id = myOther.id 和
加入所有 children 如果 top.createdBy = myUser OR
如果 top.createdBy != myUser,仅加入 children 其中 child.createdBy = myUser(或者可能没有 children)

这是我尝试过的方法(在许多其他失败的变体中):

Top.createCriteria().list{
  eq('other', myOther)
  createAlias('children', 'c', JoinType.LEFT_OUTER_JOIN)
  children {
    or {
      isNull('c')
      eq('createdBy', myUser)
      and {
        ne('createdBy', myUser)
        eq('c.createdBy', myUser)
      }
    }
  }
}

但这失败了 "org.hibernate.QueryException: duplicate association path: children" 和无用的堆栈跟踪。

有什么提示吗?提前致谢!

您可以通过执行左连接来避免 "duplicate association path" 错误,如下所示。并删除别名

children(CriteriaSpecification.LEFT_JOIN) {
    or {
     ........
  }

未测试但试试这个

Top.createCriteria().list{
  eq('other', myOther)
  or {
    eq "createdBy", myUser
    children(CriteriaSpecification.LEFT_JOIN) {
        eq "createdBy", myUser
    }
  }

}

对于 Grails 3 的条件内连接

import org.hibernate.criterion.Restrictions

...
...

Top.createCriteria().list{   
    eq('other', myOther)   
    createAlias('children', 'c', JoinType.LEFT_OUTER_JOIN, Restrictions.or(Restrictions.eq("c.createdBy", myUser))   

    ne('createdBy', myUser)

}

这将在标准级别添加条件,并生成 sql 附近与以下相同的条件。

Select
...
...

left outer join
        child ch1_ 
            on top_.id=ch1_.id 
            and (
                ch1_.createdBy=? 
            ) 
where
 top_.createdBy <> ?