3
votes

I am new to Grails, I tried to save domain object by calling save() in my *service.groovy as shown below

render " ${user.username}"
render " ${user.email}"
render " ${user.password}"
def savedUser = user.save(flush: true)
if(savedUser!=null) {
    return savedUser
} else {
    return user
}

The render shows all elements have the values which have been passed from controller. but an NullPointerexception is thrown in save(). the actual error got is

ERROR errors.GrailsExceptionResolver - NullPointerException occurred when processing request: [POST]

Validation error might have occurred, but I checked all validation error in controller by using command class.

How can avoid the exception here?

1
Can you exactly add the full implementation of the above logic from the service class? render is used in controller not in service classes in general. Did not get about the validation statement. Also try if you see any errors if you try user.save(flush: true, failOnError: true). - dmahapatro
i checked all these cases user.save(flush: true),user.save(validate: false), user.save(deepValidate: false) but still shows nulpointer. - An Ish A
you might consider putting grails.gorm.failOnError = true in your Config.groovy. fail early... - cfrick
It's a really bad idea to globally use failOnError. Exceptions are expensive and even more so in Groovy, and it's not a good idea to generate unnecessary exceptions for non-exceptional cases like user error when filling out forms and submitting data. Just check if there was a validation error - it's basically the same code as a try/catch and doesn't incur the runtime cost of filling in all those stack frames which aren't used. - Burt Beckwith

1 Answers

1
votes

That's pretty nonstandard code. Rather than checking for a null return value, it's more common (and sensible/useful) to check if there were validation errors. E.g.

user.save(flush: true)
if (user.hasErrors()) {
   // do something with the invalid "user" instance
}
else {
   // do something with the valid "user" instance
}

For your scenario, you can ignore the return value and just work with the original instance:

user.save(flush: true)
return user

If you're working with the standard templates (or something similar) then this should work fine since there's logic there to check if there are attached errors and display them.