说我有以下(大大简化)GORM域类:
class PhoneCall extends Interaction {
Survey survey
}
class Survey {
String campaignCode
Integer clientId
Boolean isDynamic
List interactions
static constraints = {
campaignCode unique: true, nullable: false
clientId nullable: true
isDynamic nullable: true
}
static hasMany = [interactions: Interaction]
}
class Interaction {
String clazz
Instant dateCreated
static constraints = {
}
static mapping = {
tablePerHierarchy false
autoTimestamp false
}
def beforeInsert() {
dateCreated = Instant.now()
}
}
我有以下简单的代码来为测试设置这些类:
def survey = new Survey(campaignCode: "TEST", isDynamic: true).save(failOnError: true, flush: true)
def phoneCall = new PhoneCall(survey: survey, clazz: PhoneCall.name).save(failOnError: true)
以下堆栈跟踪失败:
org.springframework.dao.DataIntegrityViolationException: could not insert: [uk.co.nttfundraising.onitfhi.domain.PhoneCall]; SQL [insert into phone_call (id) values (?)]; constraint [survey_id]; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [uk.co.nttfundraising.onitfhi.domain.PhoneCall]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:643)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.SavePersistentMethod.performSave(SavePersistentMethod.java:56)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractSavePersistentMethod.doInvokeInternal(AbstractSavePersistentMethod.java:215)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractDynamicPersistentMethod.invoke(AbstractDynamicPersistentMethod.java:63)
at org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi.save(HibernateGormInstanceApi.groovy:196)
但是,如果我从List interactions
删除行Survey
(将interactions
变为Set
),一切正常。如果我使用SortedSet interactions
也没有问题,虽然生成的数据库模式似乎没有任何顺序概念,所以我不确定该解决方案。 Google主要建议不保存Survey
(例如this blog post),但我已经尝试过无效。
只有List
失败,导致插入PhoneCall
完全忽略我的Survey
!发生了什么事?
答案 0 :(得分:1)
使用List
时需要注意的是,在添加到save()
之前,您添加到其中的项目不能List
。但更重要的是,在使用一对多关联时向集合添加项目的正确方法是使用survey.addToInteractions()
,请参阅addTo*()。但首先,你需要一个适当的关联......
class PhoneCall extends Interaction {
static belongsTo = [survey: Survey]
}
将Survey
属性替换为belongsTo
,即可获得正确的bi-directional one-to-many association。然后,您可以像这样使用/测试它:
def survey = new Survey(campaignCode: "TEST", isDynamic: true)
survey.addToInteractions(new PhoneCall(survey: survey, clazz: PhoneCall.name))
survey.save(failOnError: true, flush: true)
请注意,PhoneCall
从未明确保存,并且未明确指定PhoneCall.survey
。调用survey.save()
时,所有这些都得到了解决。
保存后,someSurvey.interactions[index].survey
将引用someSurvey
。