First off I am using Grails 1.02. My problem is that it appears domain class are not enforcing validation across the hasMany properties. When you save the owning side of the hasMany relationship the validation on the other side of the object relationship does not seem to occur.
I've got a Picture domain class which has many PictureTag objects. A PictureTag's name property has a maxSize constraint of 25. When I create a new picture and add a tag having a name greater than 25 characters the following happens on saving the parent picture object:
org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: could not insert: [PictureTag]; uncategorized SQLException for SQL [insert into picture_tag (version, name) values (?, ?)]; SQL state [01004]; error code [0]; Data truncation: Data too long for column 'name' at row 1; nested exception is com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'name' at row 1
It broke because I had a PictureTag object with name property greater than 25 characters. The field in the tag database table has length of 25, hence truncation. Why did the validation not catch this before the save could go any further?
Validation is working properly for the Picture objects properties. I also have no problems with referenced objects being validated in one to one and one to many scernarios. Is this just a broken feature of 1.0.2?
// Code follows
class PictureTag {
String name
static belongsTo = Picture
static hasMany = [pictures:Picture]
static constraints = {
name(nullable: false, blank: false, maxSize: 25, validator: { val, obj ->
println "${val}, ${obj}"
})
pictures(nullable: false) // must belong to at least 1 picture
}
String toString() { "$id :: $name" }
}
class Picture {
String appTag // RFC 4151 tag, for APP entry id
String title
String description = ""
Boolean shared = false
Boolean disowned = false
Date submitted = new Date()
Date updated
static belongsTo = [owner:BlcUser]
static hasMany = [tags:PictureTag]
def picsService
static constraints = {
title(blank: false, nullable: false, maxSize: 255,validator: { title, picture ->
picture.picsService.picExists(picture.owner, title) ? ['alreadyused', title] : true
})
description(nullable: false, maxSize: 16777215)
owner(nullable: true)
}
public Boolean hasTagNamed(String name)
{
tags.each { tag -> if(tag.getName().equals(name)) return true; }
return false;
}
String toString() { "${id} :: ${title}: ${description}" }
}