Scenario 1:
I have two classes:
Post:
class Post {
String content
Date dateCreated
static constraints = {
content(blank: false)
}
static belongsTo = [ user : User ]
}
User:
class User {
// existing code here
static hasMany = [ posts : Post ]
}
Its a classical one-many relationship. The integration test for these classes:
void testFirstPost() {
def user = new User(userId: 'joe',password: 'secret').save()
def post1 = new Post(content: "First post... W00t!")
user.addToPosts(post1)
def post2 = new Post(content: "Second post...")
user.addToPosts(post2) }
Works very well. But if you consider the other two classes like:
Scenario 2:
User:
class User {
String login
String password
Profile profile
Status status
static hasMany = [ holidays : Holiday ]
static constraints = {
login(unique:true,size:2..20)
password(size:2..20) //more to be added later!
profile(nullable:true)
company(nullable:true)
}
static belongsTo = [ company : Company ]
}
Company:
class Company {
String shortName;
String name
Date dateCreated
String region
String email
Address address
Status status
Long tel
Long fax
static hasMany = [ users : User]
static constraints = {
}
static mapping = {
address lazy:false
status lazy:false
}
}
Again the classical one-many relationship.
For these classes, I have written the test like this:
void testSaveUser() {
def status1 = new Status(name:"Busy")
status1.save(flush:true)
def user = new User(login:"anto",password:"anything",
status:status1)
assert user.save(flush:true, failOnError: true)
}
Even this test works fine. Note that in second User class, I have made the constraint for company field as company(nullable:true), if I didn’t put this the above test(testSaveUser()) fails!.
The error I’m getting is this:
Validation Error(s) occurred during save(): - Field error in object 'mnm.User' on field 'company': rejected value [null]; codes [mnm.User.company.nullable.error.mnm.User.company,mnm.User.company.nullable.error.company,mnm.User.company.nullable.error.mnm.Company,mnm.User.company.nullable.error,user.company.nullable.error.mnm.User.company,user.company.nullable.error.company,user.company.nullable.error.mnm.Company,user.company.nullable.error,mnm.User.company.nullable.mnm.User.company,mnm.User.company.nullable.company,mnm.User.company.nullable.mnm.Company,mnm.User.company.nullable,user.company.nullable.mnm.User.company,user.company.nullable.company,user.company.nullable.mnm.Company,user.company.nullable,nullable.mnm.User.company,nullable.company,nullable.mnm.Company,nullable]; arguments [company,class mnm.User]; default message [Property [{0}] of class [{1}] cannot be null]
grails.validation.ValidationException: Validation Error(s) occurred during save():
- Field error in object 'mnm.User' on field 'company': rejected value [null]; codes [mnm.User.company.nullable.error.mnm.User.company,mnm.User.company.nullable.error.company,mnm.User.company.nullable.error.mnm.Company,mnm.User.company.nullable.error,user.company.nullable.error.mnm.User.company,user.company.nullable.error.company,user.company.nullable.error.mnm.Company,user.company.nullable.error,mnm.User.company.nullable.mnm.User.company,mnm.User.company.nullable.company,mnm.User.company.nullable.mnm.Company,mnm.User.company.nullable,user.company.nullable.mnm.User.company,user.company.nullable.company,user.company.nullable.mnm.Company,user.company.nullable,nullable.mnm.User.company,nullable.company,nullable.mnm.Company,nullable]; arguments [company,class mnm.User]; default message [Property [{0}] of class [{1}] cannot be null]
at mnm.UserIntegrationTests.testSaveUser(UserIntegrationTests.groovy:18)
Even though the both Scenario 1 and Scenario 2 are same, why does the Scenario 2 forces me to add the company(nullable:true) constraint?
(Note that I’m using Grails 1.3.7 and ran the two Scenarios in the same version!.)
Thanks in advance.
If something
belongsTosomething else, by default it cannot benullIn your test, you do not (still) set a
companyfor the user before yousaveit, so it will fail with the default constraint