grailsgrails-2.3

grails 2.3.x: Strange behavior with autogenerated controller


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.


Solution

  • 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.