开发者

Grails: Duplicates & unique constraint validation

开发者 https://www.devze.com 2022-12-31 23:40 出处:网络
OK here is stripped down version of what I have in my app Artist domain: class Artist { String name Date lastMined

OK here is stripped down version of what I have in my app

Artist domain:

class Artist {

    String name
    Date lastMined
    def artistService

    static transients = ['artistService']
    static hasMany = [events: Event]

    static constraints = {
        name(unique: true)
        lastMined开发者_开发知识库(nullable: true)
    }

    def mine() {
        artistService.mine(this)
    }
}

Event domain:

class Event {

    String name
    String details
    String country
    String town
    String place
    String url
    String date

    static belongsTo = [Artist]
    static hasMany = [artists: Artist]

    static constraints = {
        name(unique: true)
        url(unique: true)
    }
}

ArtistService:

class ArtistService {

    def results = [
        [
            name:"name",
            details:"details",
            country:"country",
            town:"town",
            place:"place",
            url:"url",
            date:"date"
        ]
    ]

    def mine(Artist artist) {
        results << results[0] // now we have a duplicate
        results.each {
            def event = new Event(it)
            if (event.validate()) {
                if (artist.events.find{ it.name == event.name }) {
                    log.info "grrr! valid duplicate name: ${event.name}"
                }
                artist.addToEvents(event)
            }
        }

        artist.lastMined = new Date()
        if (artist.events) {
            artist.save(flush: true)
        }
    }
}

In theory event.validate() should return false and event will not be added to artist, but it doesn't.. which results in DB exception on artist.save()

Although I noticed that if duplicate event is persisted first everything works as intended. Is it bug or feature? :P


You should replace artist.addToEvents(event) by artist.addToEvents(event).save() and it will work. Till you didn't call save() method, the validation will not take into account the new created event


Which version of Grails? I've just tested this code in the Grails 1.3.1 console:

new Book(title: "Misery", author: "Stephen King").save()
new Book(title: "The Shining", author: "Stephen King").save()
new Book(title: "Colossus", author: "Niall Ferguson").save(flush: true)

def b = new Book(title: "Colossus", author: "Stephen King")
assert !b.validate()
println b.errors

The assertion passed and the last line generated output like:

org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'Book' on field 'title': rejected value [Colossus]; codes [Book.title.unique.error.Book.title,...

Perhaps it was a bug that's now fixed?

0

精彩评论

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