添加GORM域类时列表与设置

时间:2016-04-06 15:13:30

标签: grails gorm grails-domain-class

说我有以下(大大简化)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!发生了什么事?

1 个答案:

答案 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