4

我的问题应该很明显,但我现在看不到光明:-(

我有两个这样的域类:

class Parent {
  String name
  static hasMany = [children: Child]
}

class Child {
  String name
}

现在我应该能够通过使用 Parent 的动态查找器来找到孩子的父母,例如:

Parent.findByChildren([someChild] as Set)

但是我收到一个休眠错误,指出我的休眠 SQL 中有语法错误:

Caused by: java.sql.SQLException: No value specified for parameter 1

供参考: someChild 是一个具体实例。而且我想避免 Child 在定义中有明确的父母。

那我怎么能从孩子到父母呢?

此致,

克里斯蒂安·索内·詹森

4

4 回答 4

3

只是为了结束这个问题,我想报告我的“问题”的解决方案。我在父实体(客户或生产者)中使用 namedQuery,如下所示:

Class Customer {

  static hasMany = [channels: Channel]

  static namedQueries = {
   findByChannel {
        channelId ->
          channels {
              eq 'id', channelId
      }
    }
  }
}

然后我找到这样的客户:

def customers = Customer.findByChannel(channel.id).list()

这样一来,Channel 就无需知道谁引用了它,我也不必做任何人为的关系表。

我仍然认为我不能使用其中一个动态查找器一定是某种错误:

Customer.findByChannels([channel] as Set)

也许动态查找器没有考虑到一对多的关系,只适用于简单的属性???(我使用的是 Grails 1.3.1)

不过感谢您的回复!

克里斯蒂安·索内·詹森

于 2010-06-30T05:02:46.007 回答
1

如果您不希望子代上的父外键,则必须为父代创建一个连接表,作为子代的代理:

class ParentalRelationship { 
    static belongsTo = [parent: Parent, child: Child]
}

然后,您可以在父对象上使用辅助方法来通过 ParentalRelationship 对象查询子对象。

如果您真正实现了客户、渠道和生产者,那么您很可能希望建立多对多关系,因为渠道不属于单个客户(或单个生产者)。

于 2010-06-30T03:52:55.493 回答
1

也许更好的方法是写这样chieldbelongsTo东西:

static belongsTo = [parent: Parent]

然后你可以使用:

Chield c = ...
Parent parent = c.parent
于 2012-02-07T16:57:35.103 回答
0

我会反转它:

class Parent {
  String name

  static Set<Child> getChildren() {
    Child.findAllByParent(this) as Set
  }
}

class Child {
  String name
  Parent parent
}

这使用相同的数据库结构(子表对父表有一个外键),但可以轻松地从一侧转到另一侧,而无需显式双向。

一件事确实发生了变化。而不是这个:

def parent = ...
parent.addToChildren(new Child(...))
parent.save()

你来做这件事:

def parent = ...
def child = new Child(parent: parent, ...).save()

这更高效,因为您不需要加载整个集合来保存一个新的孩子。

于 2010-06-29T05:43:20.667 回答