Grails使用joinTable进行一对多映射

Grails使用joinTable进行一对多映射,grails,groovy,mapping,gorm,Grails,Groovy,Mapping,Gorm,我有两个域类。一个是“合作伙伴”,另一个是“客户”。客户可以是合作伙伴的一部分,合作伙伴可以有一个或多个客户: class Customer { Integer id String name static hasOne = [partner:Partner] static mapping = { partner joinTable:[name:'PartnerMap',column:'partner_id',key:'customer_id']

我有两个域类。一个是“合作伙伴”,另一个是“客户”。客户可以是合作伙伴的一部分,合作伙伴可以有一个或多个客户:

class Customer {
    Integer id
    String name
    static hasOne = [partner:Partner]
    static mapping = {
        partner joinTable:[name:'PartnerMap',column:'partner_id',key:'customer_id']
    }
}

class Partner {
    Integer id
    static hasMany = [customers:Customer]
    static mapping = {
        customers joinTable:[name:'PartnerMap',column:'customer_id',key:'partner_id']
    }
}
但是,每当我尝试查看客户是否是合作伙伴的一部分时,如下所示:

def customers = Customer.list()
customers.each {
     if (it.partner) {
          println "Partner!"
     }
}
我得到以下错误:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query; SQL [select this_.customer_id as customer1_162_0_, this_.company as company162_0_, this_.display_name as display3_162_0_, this_.parent_customer_id as parent4_162_0_, this_.partner_id as partner5_162_0_, this_.server_id as server6_162_0_, this_.status as status162_0_, this_.vertical_market as vertical8_162_0_ from Customer this_]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query
Grails似乎认为partner_id是客户查询的一部分,而不是。。。它位于PartnerMap表中,该表应该查找customer_id,然后从相应的Partner_id中获取Partner

有人知道我做错了什么吗


编辑:我忘了提到我正在对遗留数据库表执行此操作。所以我有一个Partner、Customer和PartnerMap表。PartnerMap只有一个customer\u id和partner\u id字段。

考虑到1-many在需要联接表时的工作方式,我认为标准GORM不可能使其双向并访问客户的合作伙伴。但您可以将联接表映射到域类,并通过以下方式访问:

客户:

class Customer {
   String name
   def getPartner() {
      PartnerMap.findByCustomer(this)?.partner
   }
}
合作伙伴:

class Partner {
   String name
   def getCustomers() {
      PartnerMap.findAllByPartner(this)*.customer
   }
}
PartnerMap:

import org.apache.commons.lang.builder.HashCodeBuilder

class PartnerMap implements Serializable {

   Partner partner
   Customer customer

   boolean equals(other) {
      if (!(other instanceof PartnerMap)) {
         return false
      }

      other.partner?.id == partner?.id &&
         other.customer?.id == customer?.id
   }

   int hashCode() {
      def builder = new HashCodeBuilder()
      if (partner) builder.append(partner.id)
      if (customer) builder.append(customer.id)
      builder.toHashCode()
   }

   static PartnerMap get(long partnerId, long customerId) {
      find 'from PartnerMap where partner.id=:partnerId and customer.id=:customerId',
         [partnerId: partnerId, customerId: customerId]
   }

   static PartnerMap create(Partner partner, Customer customer, boolean flush = false) {
      new PartnerMap(partner: partner, customer: customer).save(flush: flush, insert: true)
   }

   static boolean remove(Partner partner, Customer customer, boolean flush = false) {
      PartnerMap instance = PartnerMap.findByPartnerAndCustomer(partner, customer)
      instance ? instance.delete(flush: flush) : false
   }

   static void removeAll(Partner partner) {
      executeUpdate 'DELETE FROM PartnerMap WHERE partner=:partner', [partner: partner]
   }

   static void removeAll(Customer customer) {
      executeUpdate 'DELETE FROM PartnerMap WHERE customer=:customer', [customer: customer]
   }

   static mapping = {
      id composite: ['customer', 'partner']
      version false
      table 'PartnerMap'
   }
}

由于没有使用hasMany,因此会丢失addToXXX动态方法,但可以调用
PartnerMap.create()
来关联两个实例。您也会丢失域类中的集合和back ref,但我为它们添加了实用方法。

Oops,我忘了提一下,我正在使用遗留数据库的东西来完成此操作。。。因此,我必须使用预定义的表。我有一个客户、合作伙伴和PartnerMap表。PartnerMap只是一个客户id和合作伙伴id字段。这会限制我吗?我刚刚意识到这个问题只存在于试图在Grails控制台中加载这些东西时。我不知道为什么。。。我假设Grails控制台可以像Rails那样适当地加载环境……我重新编写了代码,但是如果它在控制台之外工作,那么应该使用更简单的解决方案。控制台非常接近Grails运行时环境,但在运行应用程序中或在战争中部署时会发生很多事情,控制台仅与该环境接近。感谢您的帮助!我只是觉得编写一个虚拟控制器并在其中编写一些快速测试代码更容易,以确保我的域类按预期工作,并且它们是正确的。仅仅使用一个在grails控制台中具有关系的域类就需要这么多,这是一个令人沮丧的问题。。。