Spring Roo
  1. Spring Roo
  2. ROO-581

Create and update views don't allow nullable reference field to be null

    Details

    • Type: Improvement Improvement
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.0.1.RELEASE
    • Fix Version/s: None
    • Component/s: WEB MVC
    • Labels:
      None

      Description

      Imagine a reference field that can be null (e.g. a Car can have a Radio or not). There are two problems with the auto-generated views for the Car entity (assuming some Radios have already been added to the database):

      • in car/create.jspx, the "Radio" drop-down defaults to blank, but if no Radio is selected, the form fails to submit and shows no error (presumably there is a binding and/or validation problem)
      • in car/update.jspx, you can't change a Car from having a Radio to not having a Radio, because the select tag doesn't have a null option even though the Car.radio field can be null in Java.

      Here's a test script that demonstrates the problem:

      project --topLevelPackage test
      persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY 
      entity --class ~.domain.Car
      entity --class ~.domain.Radio
      field reference --class ~.domain.Car --fieldName radio --type ~.domain.Radio
      controller all --package ~.web

      Here's the original view code for the "Radio" field (in both the above views):

      <form:select cssStyle="width:250px" id="_radio_id" path="radio">
          <form:options itemValue="id" items="${radios}" />
      </form:select>

      To fix this, you have to edit both create.jspx and update.jspx to include a null option like this:

      <form:select cssStyle="width:250px" id="_radio_id" path="radio">
          <form:option value="" label="(none)"/> <!-- Add this line -->
          <form:options itemValue="id" items="${radios}" />
      </form:select>

      And register a custom PropertyEditor in CarController as follows:

      @InitBinder
      public void initBinder(final WebDataBinder binder) {
          binder.registerCustomEditor(Radio.class, new PropertyEditorSupport() {
              @Override
              public void setAsText(final String text) {
                  if (StringUtils.hasText(text)) {
                      setValue(Radio.findRadio(Long.valueOf(text)));
                  }
                  else {
                      setValue(null);
                  }
              }
          });
      }

      This workaround should not be necessary, given that Roo knows all along that the field can be null.

        Issue Links

          Activity

          Hide
          Stefan Schmidt added a comment -

          I have created a SFW ticket to see if we can get this done in the framework rather than using a workaround in Roo.

          Show
          Stefan Schmidt added a comment - I have created a SFW ticket to see if we can get this done in the framework rather than using a workaround in Roo.
          Hide
          Luca Preziati added a comment -

          I have edited select.tagx which permit to enable empty value editing the jsp.

          Show
          Luca Preziati added a comment - I have edited select.tagx which permit to enable empty value editing the jsp.
          Hide
          Luke Way added a comment -

          I also put the modified form:select tag in select.tagx. This of course makes it apply to all select boxes, but that's OK for me.

          Additionally, I added "required: $

          {required}

          " to widgetAttrs of dijit.form.FilteringSelect (also in select.tagx). Without this, the form would not submit blank values, saying the field was required.

          Finally, I did not need the custom PropertyEditor at all. I am using Oracle, which treats empty strings as NULL, anyway.

          Show
          Luke Way added a comment - I also put the modified form:select tag in select.tagx. This of course makes it apply to all select boxes, but that's OK for me. Additionally, I added "required: $ {required} " to widgetAttrs of dijit.form.FilteringSelect (also in select.tagx). Without this, the form would not submit blank values, saying the field was required. Finally, I did not need the custom PropertyEditor at all. I am using Oracle, which treats empty strings as NULL, anyway.
          Hide
          Scott Murphy added a comment -

          Hey Stefan, do you have a reference to the SFW ticket you created that I can follow?

          Show
          Scott Murphy added a comment - Hey Stefan, do you have a reference to the SFW ticket you created that I can follow?
          Hide
          Scott Murphy added a comment -

          Never mind, I see that it is referenced in this ticket.

          Show
          Scott Murphy added a comment - Never mind, I see that it is referenced in this ticket.

            People

            • Assignee:
              Unassigned
              Reporter:
              Andrew Swan
            • Votes:
              37 Vote for this issue
              Watchers:
              26 Start watching this issue

              Dates

              • Created:
                Updated: