说我有以下(大大简化的)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!这是怎么回事?

最佳答案

使用List的一个警告是,添加到其中的项目在添加到save()之前不能是List d。但更重要的是,使用一对多关联时将项添加到集合中的正确方法是使用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

关于grails - 添加GORM域类时列出与设置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36455280/

10-10 02:43