开发者

Grails unique test fails after interchanging attribute values

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 constrain开发者_如何学运维t 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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜