Grails unique test fails after interchanging attribute values

大兔子大兔子 提交于 2019-12-10 11:47:17

问题


Hello I am trying to implement a simple translation list, meaning I have a values and translations to this values.

[Edit:] As this is part of my user interface and values and translations shall be exportable via xml, using the i18n files seams quite inconvinient for this proposition. Thats why I decided to store them in a database.

I have one domain class for a value:

class Value {
    String label
    static hasMany = [ translations: Translation ]
}

and one for translations with a unique constraint to ensure that for one value there must'nt be more than one translation for a specific language:

class Translation {
    String value
    Language language

    static belongsTo = [ value: Value ]

    static constraints = {
        language(unique: 'value')
    }
}

My problem occures after interchanging two translation languages for the same value. Example:

value.translations.each() { translation ->
    println "${value.label} in ${translation.language.label} is ${translation.value}"
}

// process updates...

value.translations.each() { translation ->
    println "${value.label} in ${translation.language.label} is ${translation.value}"
}

// validate...

prints out

Comedy in german: Comedy
Comedy in english: Komödie   

Comedy in english: Comedy
Comedy in german: Komödie

so the unique constraint is not violated before and after the update, but anyhow I get an unique constraint failure while saving. Another strange thing is, that I only get this error when I execute the each() loop on value. If I don't inspect the contents, the validation passes and the save(flush:true) method returns true, but the values will not be changed in the database.

[Edit:] I believe that the problem is on database level when only one value is altered and the other isn't, because exactly in that state the constraint is violated. If the changes would be executed as a transaction instead and the constraints would not be checked during this intermediate step this could be avoided. (this might be the thing, i am looking for)

Another way to avoid this would be to delete and recreate every edited bean but I was hoping that there might be a more convenient way to do this.

Thanks for any help


回答1:


The constraint is checked when an implicit or explicit flush() happens. At that moment, GORM checks if there exists another such a value in a database. So, if one instance is already flush()ed and another is not yet, you'll get a constraint violation.

Try not to flush() till the end of transaction - remove flush: true parameter or even set it to flush: false. At the end of transaction both changes should apply.

There's a caveat in Grails, JFYTK: it does an implicit flush() when executing a Criteria, so don't be too surprised about Hibernate errors when you didn't intend to flush() yet.



来源:https://stackoverflow.com/questions/6174374/grails-unique-test-fails-after-interchanging-attribute-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!