Spring Framework
  1. Spring Framework
  2. SPR-4452

Make @ModelAttribute's not required...

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 2.5.1
    • Fix Version/s: None
    • Component/s: Web
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      Its a pain in the backside if you want your GET request to have access to the session object, since you have to create it first.

      Think of some type of workflow/data entry... they go to the page, they save their progress (but you don't want to commit to the database yet because they aren't done)... then they click the link to go back to the edit page, you have to write special code to make it all come together...

      If you could just check for null, you'd know whether to create the model object or just keep chugging along.

        Activity

        Hide
        Miguel Vargas added a comment -

        When using @ModelAttribute with @SessionAttribute, there is no way of gracefully handling users without cookies on a server that only supports cookie based sessions. If @ModelAttribute had a required=false option one could detect the null object and react accordingly.

        Show
        Miguel Vargas added a comment - When using @ModelAttribute with @SessionAttribute, there is no way of gracefully handling users without cookies on a server that only supports cookie based sessions. If @ModelAttribute had a required=false option one could detect the null object and react accordingly.
        Hide
        Aaron Hamid added a comment -

        Yes please. Especially when trying to coordinate interactions of multiple controllers through use of session attributes, this can be annoying. Without optional ModelAttribute (or optional SessionAttribute, however you want to look at it), there is no way for a controller to opportunistically take advantage of an attribute in the session if it exists, or do something else (create a new instance or load one from somewhere) otherwise.

        Show
        Aaron Hamid added a comment - Yes please. Especially when trying to coordinate interactions of multiple controllers through use of session attributes, this can be annoying. Without optional ModelAttribute (or optional SessionAttribute, however you want to look at it), there is no way for a controller to opportunistically take advantage of an attribute in the session if it exists, or do something else (create a new instance or load one from somewhere) otherwise.
        Hide
        Rossen Stoyanchev added a comment -

        (Eric): they go to the page, they save their progress (but you don't want to commit to the database yet because they aren't done) ... then they click the link to go back to the edit page, you have to write special code to make it all come together...

        One way or another the model attribute needs to be loaded. This is typically done on the initial GET when the edit form is loaded. I don't see how "going back to the edit page" is any different from "going to the page" the first time. The same code should load the object in both cases.

        (Miguel): If @ModelAttribute had a required=false option one could detect the null object and react accordingly.

        You can use a @ModelAttribute method for that. See my notes below.

        (Aaron): when trying to coordinate interactions of multiple controllers through use of session attributes

        @SessionAttributes was designed for scenarios where there is a specific entry point, i.e. a method where the object gets loaded for the first time and remains around until SessionStatus.setComplete() is called. For example when editing a form, the model attribute is loaded on access to the form page and is kept in the session until after the POST or PUT that saves or updates it.

        For a scenario where multiple controllers share a session object and there is no obvious entry point, you could use a method like the one below to pre-load it if necessary so that your @RequestMapping method can still take advantage of data binding and validation as usual:

        @ModelAttribute
        public MyObject getMyObject(ModelMap model) {
            MyObject myObject = model.get("myObject");
            if (myObject == null) {
                // ...
            }
            return myObject;
        }
        
        @RequestMapping(method=RequestMethod.PUT)
        public String update(@Valid @ModelAttribite MyObject myObject, Errors errors) {
            if (errors.hasErrors()) {
                return "formView";
            }
            return "successView";
        }
        

        Suppose we added a required=false option. You would still end up with very similar code except no data binding nor validation:

        @RequestMapping
        public String update(@ModelAttribite(required=false) MyObject myObject, Errors errors, ModelMap model) {
            if (myObject == null) {
                // load myObject here
                model.addAttribute("myObject", myObject);
            }
        
            // Errors is null
            // Too late for automated data binding and validation here
        
        }
        
        Show
        Rossen Stoyanchev added a comment - (Eric): they go to the page, they save their progress (but you don't want to commit to the database yet because they aren't done) ... then they click the link to go back to the edit page, you have to write special code to make it all come together... One way or another the model attribute needs to be loaded. This is typically done on the initial GET when the edit form is loaded. I don't see how "going back to the edit page" is any different from "going to the page" the first time. The same code should load the object in both cases. (Miguel): If @ModelAttribute had a required=false option one could detect the null object and react accordingly. You can use a @ModelAttribute method for that. See my notes below. (Aaron): when trying to coordinate interactions of multiple controllers through use of session attributes @SessionAttributes was designed for scenarios where there is a specific entry point, i.e. a method where the object gets loaded for the first time and remains around until SessionStatus.setComplete() is called. For example when editing a form, the model attribute is loaded on access to the form page and is kept in the session until after the POST or PUT that saves or updates it. For a scenario where multiple controllers share a session object and there is no obvious entry point, you could use a method like the one below to pre-load it if necessary so that your @RequestMapping method can still take advantage of data binding and validation as usual: @ModelAttribute public MyObject getMyObject(ModelMap model) { MyObject myObject = model.get( "myObject" ); if (myObject == null ) { // ... } return myObject; } @RequestMapping(method=RequestMethod.PUT) public String update(@Valid @ModelAttribite MyObject myObject, Errors errors) { if (errors.hasErrors()) { return "formView" ; } return "successView" ; } Suppose we added a required=false option. You would still end up with very similar code except no data binding nor validation: @RequestMapping public String update(@ModelAttribite(required= false ) MyObject myObject, Errors errors, ModelMap model) { if (myObject == null ) { // load myObject here model.addAttribute( "myObject" , myObject); } // Errors is null // Too late for automated data binding and validation here }
        Hide
        Rossen Stoyanchev added a comment -

        Resolving is "Won't Fix". The issue can be re-opened if necessary but I'm not sure the suggestion is feasible.

        Show
        Rossen Stoyanchev added a comment - Resolving is "Won't Fix". The issue can be re-opened if necessary but I'm not sure the suggestion is feasible.

          People

          • Assignee:
            Rossen Stoyanchev
            Reporter:
            Eric Anderson
            Last updater:
            Trevor Marshall
          • Votes:
            7 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              1 year, 47 weeks, 3 days ago