Reputation: 35
A fresh grails 2.3.x project. Im using autogenerated controller and views for a domain class. One (not null) property i want to set directly in controller, so i removed the input field from the _form.gsp.
Domain class:
class Demo {
String demo
String status
static constraints = {
demo nullable: false
status nullable: false
}
In form i only fill the demo field.
Autogenerated controller results in:
...
@Transactional
def save(Demo demoInstance) {
if (demoInstance == null) {
notFound()
return
}
// set the status property to "test"
demoInstance.status = "test"
println "1 STATUS: ${demoInstance.status}"
if (demoInstance.hasErrors()) {
println "2 STATUS: ${demoInstance.status}"
respond demoInstance.errors, view: 'create'
return
}
println "3 STATUS: ${demoInstance.status}"
...
Fill the form and leave the status property blank results in
println 1 -> status = 'test'
println 2 -> status = 'test'
Redirect to create page with a message: "Property [status] of class [Demo] cannot be null"
When i change the controller as in grails 2.2.x:
...
@Transactional
def save() {
def demoInstance = new Demo(params)
if (demoInstance == null) {
notFound()
return
}
// set the status property to "test"
demoInstance.status = "test"
println "1 STATUS: ${demoInstance.status}"
if (demoInstance.hasErrors()) {
println "2 STATUS: ${demoInstance.status}"
respond demoInstance.errors, view: 'create'
return
}
println "3 STATUS: ${demoInstance.status}"
...
This results in the expected output:
println 1 -> status = 'test'
println 3 -> status = 'test'
And the input is stored in Database.
Can anyone explain this behavior? Thanks.
Upvotes: 1
Views: 85
Reputation: 75671
I don't know why you're seeing the behavior you're seeing with the 2.2.x code, but the 2.3.x behavior looks correct to me regardless of which data binder you use. Data binding occurs before the controller action is called and since you left a property unset, the instance has a validation error. You then set a valid value but don't call validate()
or save()
, so there's no reason to expect that hasErrors()
would change from false to true.
If you add
demoInstance.validate()
after
demoInstance.status = "test"
then I would expect to see the output you're seeing in your 2.2.x version (although again, without a validate
or save
call I can't imagine why it would work in 2.2 either).
Upvotes: 1
Reputation: 26
I had the same issue. Do not know the exact reason, but what works is:
bindData(demoInstance, [status: 'test'])
Grails 2.3 has a new DataBinding. you can use the old Spring style if you set
grails.databinding.useSpringBinder = true
in Config.groovy
Using this SpringBinder, this issue does not occur.
Upvotes: 1