I have a controlle开发者_如何学Cr with 2 methods that return related objects via the @ModelAttribute annotation:
@ModelAttribute("site")
public Site getSite(){
.....
return site;
}
@ModelAttribute("document")
public Document getDocument(){
.....
return document;
}
These objects are related to each other with one Site having many Documents. This relationship is mapped in JPA. Both of these objects contain a field with the same name, called "urlAlias". This field is edited on a page using the following freemarker markup:
<@spring.bind "document" />
....
<@spring.formInput "document.urlAlias" />
When I submit the form to the controller, I retrieve the document object using the following syntax:
@RequestMapping(method = RequestMethod.POST)
public ModelAndView create(@ModelAttribute("document") @Valid Document document, BindingResult documentResult,
@ModelAttribute("site") Site site, Model model){
...Do Stuff...
}
It appears that any value that I enter into the Document's urlAlias field has also been set in the Site object, even though I only edited the value of the field in the Document object.
I'm perplexed as to what is going on here. Am I doing something untoward by mapping more than one ModelAttribute in the same controller? Are there any other likely causes of this behaviour?
It would appear that the problem is the site parameter in the create() method in my controller:
@ModelAttribute("site") Site site
Removing that stops Spring binding to fields in that object. For future googlers, I get hold of the Site object within the create() method using the code below instead:
if (!model.containsAttribute("site")) {
throw new IllegalArgumentException("Model must contain site attribute.");
}
Site site = (Site) model.asMap().get("site");
From this it would appear that it is fine to declare more than one ModelAttribute in a controller, but only one can be used at a time as a parameter in a method.
精彩评论