无法更改Grails中的域类属性值

无法更改Grails中的域类属性值,grails,gorm,grails-2.0,grails-domain-class,Grails,Gorm,Grails 2.0,Grails Domain Class,我正在开发一个Grails2.3.7应用程序,但在使用选择框更改域属性时遇到了问题。每次尝试更改属性并保存时,我都会得到一个hibernateeexception:种族实例的标识符从X更改为Y。我不想更改种族的ID,我只想将ApplicationPersons种族从一个更改为另一个 需要注意的几点: 我正在使用相同的控制器操作来创建和更新此人 在personInstance.properties=params之前将personInstance.emericity设置为null将使保存工作正常,但

我正在开发一个Grails2.3.7应用程序,但在使用选择框更改域属性时遇到了问题。每次尝试更改属性并保存时,我都会得到一个
hibernateeexception:种族实例的标识符从X更改为Y
。我不想更改种族的ID,我只想将
ApplicationPerson
s种族从一个更改为另一个

需要注意的几点:

  • 我正在使用相同的控制器操作来创建和更新此人
  • personInstance.properties=params
    之前将
    personInstance.emericity
    设置为
    null
    将使保存工作正常,但 不知道为什么,我不想为每个协会都这样做 我想改变
  • 我意识到域模型似乎很奇怪。这是我无法更改的遗留数据库
  • 以下是我的域类:

    class ApplicationPerson implements Serializable {
        Integer appId
        Integer applicationSequenceNumber
        String firstName
        String lastName
        Ethnicity ethnicity
    
        static mapping = {
            id composite: ['appId', 'applicationSequenceNumber'],
               generator: 'assigned'
        }
    }
    
    class Ethnicity {
        String code
        String description
    
        static mapping = {
            id name: 'code', generator: 'assigned'
        }
    }
    
    这是我的
    \u form.gsp
    来更新
    种族
    (我删除了所有正在保存的其他属性):


    选择
    元素中的名称从
    种族.code
    修改为
    personInstance.etnicity.code
    ,如下所示:

    <g:select id="ethnicity" 
              name="personInstance.ethnicity.code" 
              from="${Ethnicity.list()}" 
              optionKey="code" 
              value="${personInstance?.ethnicity?.code}" />
    
    根据传入的
    code
    加载现有
    种族
    ,然后在设置属性之前在
    person
    中进行设置

    问题在于
    code
    种族
    的主键。如果
    种族
    有一个单独的标识列(例如,默认的Long
    id
    ),那么您的具体实现将在数据绑定的帮助下工作。但由于提到您正在使用遗留数据库,我想您将无法修改这些表来为
    id
    添加另一列。因此,您最好从传入的代码中
    加载
    (与get相比便宜,因为行是从hibernate缓存加载的),然后将其设置为person


    如果可能的话,您还可以看到尝试缓存种族域,因为这将是主数据,也是缓存的一个很好的候选者。

    复合键中的
    aidm
    是什么?输入错误。感谢您指出这一点。您使用迁移脚本吗?备份后自动创建数据库怎么样…?不幸的是,这并不是那么简单。这是一所大学的遗留数据库。我真的不能改变任何东西,只需要在上面创建一个应用程序。我尝试了这个,但没有任何运气。我没有。我也尝试了
    name=“applicationPerson.ocidentity.code”
    ,但运气不好(不,当我进行更改时,它根本不会更改人的种族。有点像数据绑定不会发生。我还发现奇怪的是,在
    personInstance.Ocilization=null
    之前执行
    personInstance.properties=params
    会使一切正常。我是否可能映射了错误的域类?在数据库中,
    Person
    表中有一个
    ocidentity\u code
    字段映射到
    ocidentity
    …所以我很确定我映射正确了。请看我的更新,必须加载ocidentity,然后设置为
    Person
    。感谢更新。我会在早上试一试。我希望避免添加额外的depende连接到控制器,只需使用
    person.properties=params
    ,但看起来我不会这么简单。正如我所说的,如果种族有一个单独的id列,一切都会按预期工作。:)
    def save() {
        Application app = applicationService.getCurrentApplication()
    
        // Find/Create and save Person
        ApplicationPerson personInstance = app.person
        if (!personInstance) {
            personInstance = 
                new ApplicationPerson(appId: app.id, 
                                      applicationSequenceNumber: app.sequenceNumber)
        }
        personInstance.properties = params
    
        if (!personInstance.validate()) {
            respond personInstance.errors, view:'edit'
            return
        }
    
        personInstance.save flush:true
        redirect action: 'list'
    }
    
    <g:select id="ethnicity" 
              name="personInstance.ethnicity.code" 
              from="${Ethnicity.list()}" 
              optionKey="code" 
              value="${personInstance?.ethnicity?.code}" />
    
    //or use params.ethnicity.code
    //if name is ethnicity.code
    person.ethnicity = Ethnicity.load(params.personInstance.ethnicity.code)
    
    //or use params if name is ethnicity.code
    person.properties = params.personInstance