Grails GORM查询null hasOne关联失败

时间:2014-11-24 17:04:00

标签: grails gorm

我使用Grails 2.2.4(Grails 2.3.11中的相同行为)并拥有引用域类B的域类A

class A {
    static hasOne = [b: B]

    static constraints = { b nullable: true }
}

class B {
    static belongsTo = [a: A]
}

我试图找到A的所有具有B的实例。

A.findAllByBIsNotNull()*.b

返回B和null的列表:

[null, null, b1, b2, null, ...]

怎么样?

如果我使用

,也会发生同样的情况
A.withCriteria {
    isNotNull 'b'
}*.b

我做错了什么?

更新

我意识到问题是因为hasOne。如果不是static hasOne = [b: B],而是B b,则可行。前者将外键移动到表B,后者在表A中创建外键关系。 那么为什么查询在前一种情况下不起作用?如何在外键在B范围内时查询所有A s,而不是B

5 个答案:

答案 0 :(得分:4)

由于@Koloritnij的评论和@Alexander Suraphel的修改后的答案,我终于解决了它。 谢谢你。

如果外键位于B表上(由于hasOne),以下两个查询解决了这种情况:

使用A s查找所有B :( b不是null):

A.withCriteria {
  b {}
}

这会产生内部联接:SELECT * FROM a INNER JOIN b ON a.id=b.a_id;

在没有 A的情况下找到所有B s bnull):

A.withCriteria {
  createAlias('b', 'bAlias', CriteriaSpecification.LEFT_JOIN)
  isNull 'bAlias.id'
}

这导致左外连接:SELECT * FROM a LEFT OUTER JOIN b ON a.id=b.a_id WHERE b.id IS NULL;

答案 1 :(得分:1)

更新后:

使用B中的一个字段。让我们说B有字段name

A.withCriteria { b { isNotNull("name") }}*.b

旧答案:

问题可能出在B类的toString()

添加

String toString() { 
    getClass().name
}

到班级B并尝试重新运行查询。

答案 2 :(得分:0)

如果你只需要服用B,为什么你不能使用:

B.findAll()

或者如果是A:

 B.findAllByA(a)

<强> UPD: 使用标准:

    A.createCriteria().list{
       isNotNull 'B'
       isNull 'C'
    }

或者这是个坏主意但必须奏效:

def bList = B.createCriteria().list{
    projections{
       property 'id'
    }
    A.createCriteria().list{
      b{
       'in' ('id',bList)
      }
    }

答案 3 :(得分:0)

为了将来参考,任何想要做同样事情但使用 GORM Where 查询或 DetachedCriteria 的人,其等效项如下:

def criteria = new DetachedCriteria(A)
criteria.where {
    join('b', JoinType.LEFT)
    b {
        isNull 'id'
    }
}.list()

答案 4 :(得分:-1)

不应该这样 A.findAllBybIsNotNull()*.b(注意小写字母b)?

A.findAll("from A as a where a.b is null")