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?
精彩评论