【问题标题】:Grails finding parent by the many sideGrails 在多方寻找父母
【发布时间】:2010-06-29 05:16:57
【问题描述】:

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

我有两个这样的域类:

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

class Child {
  String name
}

现在我应该可以使用 Parent 的动态查找器找到孩子的 Parent,例如:

Parent.findByChildren([someChild] as Set)

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

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

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

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

最好的问候,

克里斯蒂安·索恩·詹森

【问题讨论】:

    标签: grails dynamic one-to-many finder


    【解决方案1】:

    为了结束这个问题,我想报告我的“问题”的解决方案。我在父实体(客户或生产者)中使用 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)

    感谢您的回复!

    克里斯蒂安·索恩·詹森

    【讨论】:

      【解决方案2】:

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

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

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

      在您真正实施客户、渠道和生产者之后,您很可能无论如何都希望建立多对多关系,因为渠道不属于单个客户(或单个生产者)。

      【讨论】:

      • Grails 管理多对多关系,还自动创建连接表。
      【解决方案3】:

      也许更好的方法是在chieldbelongsTo 中这样写:

      static belongsTo = [parent: Parent]
      

      然后你可以使用:

      Chield c = ...
      Parent parent = c.parent
      

      【讨论】:

        【解决方案4】:

        我会反转它:

        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()
        

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

        【讨论】:

        • 是的,我是按照这些思路思考的,但我想避免孩子知道它的父母。在我的真实案例中,我有一个客户和一个渠道作为父母和孩子。客户有一个频道列表,但一个频道也可以由例如生产者映射。因此,Channel 不应该知道 Customer(或 Producer),因为这会使 Channel 不那么通用。在其他实体不知道表的情况下将表映射到表是一种常见现象。我只需要知道从子级(频道)到父级(客户/生产者/其他)的语法 最好的问候
        猜你喜欢
        • 1970-01-01
        • 2021-12-15
        • 1970-01-01
        • 1970-01-01
        • 2017-08-26
        • 1970-01-01
        • 1970-01-01
        • 2014-10-27
        • 1970-01-01
        相关资源
        最近更新 更多