Grails: дубликаты и проверка уникальных ограничений

Хорошо, вот урезанная версия того, что у меня есть в моем приложении

Домен исполнителя:

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)
    }
}

Домен события:

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)
        }
    }
}

Теоретически event.validate () должен возвращать false, и событие не будет добавлено к исполнителю, но это не так .. что приводит к исключению БД для artist.save ()

Хотя я заметил, что если сначала сохраняется повторяющееся событие, все работает как задумано. Это ошибка или особенность? :П


person rukoche    schedule 23.05.2010    source источник
comment
Я не уверен, почему дублирующаяся логика не работает, но в вашем коде есть серьезная ошибка. Службы являются одиночными, но у вас есть общее состояние в этой службе - список «результатов». Он будет работать нормально, когда вы единственный пользователь своего приложения (в режиме разработки), но не будет работать, если у вас есть несколько одновременных доступов к этому методу.   -  person Burt Beckwith    schedule 24.05.2010
comment
В моем приложении результаты находятся в рамках метода, но спасибо за то, что подняли его, могут помочь в будущем.   -  person rukoche    schedule 24.05.2010


Ответы (2)


Вы должны заменить artist.addToEvents(event) на artist.addToEvents(event).save(), и он будет работать. Пока вы не вызываете метод save (), проверка не будет учитывать новое созданное событие.

person fabien7474    schedule 24.05.2010
comment
Проверил это в тестовом приложении - работает как шарм, в моем реальном приложении - по-прежнему выдает исключение повторяющейся записи. Только сохранение (flush: true) устраняет проблему: | - person rukoche; 24.05.2010

Какая версия Grails? Я только что протестировал этот код в консоли Grails 1.3.1:

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

Утверждение прошло, и последняя строка сгенерировала такой вывод:

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

Возможно, это была исправленная ошибка?

person Peter Ledbrook    schedule 24.05.2010