Uploaded image for project: 'Spring Roo'
  1. Spring Roo
  2. ROO-581

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

    Details

    • Type: Improvement
    • Status: Open
    • Priority: 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.

        Attachments

          Issue Links

            Activity

              People

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

                Dates

                • Created:
                  Updated: