Search code examples
grailsgroovygsp

Grails GSP: <g:widget ... /> throws no such property on nested Numbers


I'm currently developing a grails application (Version 3.1.2) and I got a frustrating error that I currently cannot solve.

Lets have an example case:

// Domain classes
class RootBean {
    NestedBean nestedBean
}

class NestedBean {
    int nestedInteger
}

not much to say about it, its just an 1 to 1 relation with no back reference

Now lets specify my problem: I've got a create and an edit view which both render a editTemplate with all the possible inputs. With a new Object (create) everythings works fine but with a existing Object I want to update I get this GSP Error Message:

URI
   /VMPMessung/edit/2
Class
   groovy.lang.MissingPropertyException
Message
   Request processing failed; nested exception is org.grails.gsp.GroovyPagesException: Error processing GroovyPageView: [views/rootBean/edit.gsp:13] Error executing tag <g:render>: [views/rootBean/_editTemplate.gsp:1] Error executing tag <g:form>: [views/rootBean/_editTemplate.gsp:150] Error executing tag <f:widget>: No such property: nestedInteger for class: RootBean
Caused by
   No such property: nestedInteger for class: RootBean

The GSP Code:

<f:widget class="form-control"
       property="nestedBean.nestedInteger"
       bean="RootBean"/>

I also debugged through the Taglibary and discoverd that it's going wrong cause of the Type Integer, I got other String fields in the real object and they are working fine. The Error is thrown in the FormFieldsTagLib class at line 569

private CharSequence renderNumericInput(BeanPropertyAccessor propertyAccessor,Map model, Map attrs) {
    if (!attrs.type && model.constraints?.inList) {
         attrs.from = model.constraints.inList
    if (!model.required) attrs.noSelection = ["": ""]
        return g.select(attrs)
    } else if (model.constraints?.range) {
        attrs.type = attrs.type ?: "range"
        attrs.min = model.constraints.range.from
        attrs.max = model.constraints.range.to
    } else {
        attrs.type = attrs.type ?: getDefaultNumberType(model )
        if (model.constraints?.scale != null) attrs.step = "0.${'0' * (model.constraints.scale - 1)}1"
        if (model.constraints?.min != null) attrs.min = model.constraints.min
        if (model.constraints?.max != null) attrs.max = model.constraints.max
    }

    if(propertyAccessor != null && attrs.value) {
        attrs.value = g.fieldValue(bean: propertyAccessor.rootBean, field: propertyAccessor.propertyName)
        // This call causes the Error
        // Debugging Values: propertyAccessor.rootBean: RootBean, 
        // propertyAccessor.propertyName: nestedInteger
    }
    return g.field(attrs)
}

I guess they are trying to find the fieldName on the RootBean instead of the NestedBean but am I doing something wrong or is it a Bug on Grails side?

Hopefully some of you knows an answer to this, its really much a blocker for me :(


Solution

  • I am having the same issue, the weird thing is that in I am not having problem, I have it only in

    I could fix it with a workaround, implementing in RootBean class a getter for nestedInteger:

    def int getNumber() {
        return nestedBean?.nestedInteger
    }
    

    That worked for me. Could you solve it properly?