[英]Grails one-to-many mapping with joinTable
我有兩個域類。 一個是“合作伙伴”,另一個是“客戶”。 客戶可以是合作伙伴的一部分,並且合作伙伴可以擁有1個或多個客戶:
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是Customer查詢的一部分,而不是……它位於PartnerMap表中,該表應該找到customer_id,然后從相應的partner_id中獲取Partner。
有人知道我在做什么錯嗎?
編輯:我忘了提及我正在使用舊數據庫表執行此操作。 因此,我有一個Partner,Customer和PartnerMap表。 PartnerMap僅具有一個customer_id和partner_id字段。
考慮到當您想要一個聯接表時“一對多”的工作方式,我認為使用標准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()
來關聯兩個實例。 您還會丟失域類中的集合和反向引用,但是我為它們添加了實用程序方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.