Spring multiple @ModelAttribute methods in the same @Controller

droidpl picture droidpl · Apr 17, 2013 · Viewed 9.7k times · Source

I have a page with two different forms (with two different submits) on Spring MVC 3, and I have a problem with @ModelAttribute methods. When I have two on the same controller, they are not always executed making the model to be NULL.

The code:

@Controller
@RequestMapping(value = "/session/admin/permission/{userId}")
public class PermissionController {

    @Autowired
    private UserManager userManager;

    @ModelAttribute("passwordValidation")
    private PasswordValidation getPasswordModel(){
        return new PasswordValidation();
    }

    @ModelAttribute("user")
    private User getUserModel(@PathVariable("userId") String userId){
        //This is not executed
        return userManager.getUser(userId);
    }

    @ModelAttribute("permissionsAvailable")
    private PermissionsAvailable getPermissionsModel(@ModelAttribute("user") User user)     {
        return new PermissionsAvailable();
    }

    @RequestMapping(method = RequestMethod.GET)
    public String adminPermission(){
        return "/security/permission";
    }

    @RequestMapping(method = RequestMethod.POST, params="changeRoles")
    public String modifyPermission(@ModelAttribute("permissionsAvailable") PermissionsAvailable permissions,
            HttpServletRequest request, @ModelAttribute("user") User user, 
            final RedirectAttributes redirectAttributes){
        //Modify something
    }

    @RequestMapping(method = RequestMethod.POST, params="changePassword")
    public String modifyPassword(
            @ModelAttribute("passwordValidation") PasswordValidation passwordValidation,
            @ModelAttribute("user") User user,
            HttpServletRequest request, BindingResult bindingResult, 
            final RedirectAttributes redirectAttributes){
        return "newpage";
    }
}

Don't know why, sometimes everything goes ok and every method is executed, but sometimes they are not executed.

UPDATE: I have two different controllers with the same problem so it must be an error on Spring or something I'm doing wrong.

Thanks.

Answer

sdouglass picture sdouglass · May 25, 2013

The documentation doesn't mention anywhere that it's possible to use @ModelAttribute on an argument to a @ModelAttribute annotated method, like you're doing in your "getPermissionsModel()" method. It's possible that's not supported, since it's not documented as being supported. You might want to try either removing the "@ModelAttribute("user") User user" argument from your "getPermissionsModel()" method, and/or instead try just using one @ModelAttribute method to set all your model attributes:

@ModelAttribute
public void setAttributes(@PathVariable("userId") String userId, Model model) {
    model.addAttribute(new PasswordValidation());
    model.addAttribute(userManager.getUser(userId));
    model.addAttribute(new PermissionsAvailable());
}