I have a controller used to display a list of project, but I cannot find why a @ModelAttribute method doesn't get called.
This is my controller:
@Controller(value = "projectListController")
@RequestMapping(value = "VIEW")
public class ProjectListController {
@Autowired
@Qualifier("projectService")
private ProjectService projectService;
@RenderMapping
public String showProjects() {
return "projectList";
}
@ModelAttribute("projectListCount")
public Long getProjectListCount() {
return projectService.getProjectListCount();
}
@ModelAttribute("projectFilter")
public ProjectFilter getProjectFilter(
@RequestParam(value = "cur", required = false) String curString,
@RequestParam(value = "delta", required = false) String deltaString,
@RequestParam(value = "orderByCol", required = false) String orderByCol,
@RequestParam(value = "orderByType", required = false) String orderByType) {
return new ProjectFilter(curString, deltaString, orderByCol, orderByType);
}
@ModelAttribute("projectList")
public List<TPrProgetti> getProjectList(
@ModelAttribute("projectFilter") ProjectFilter projectFilter) {
return projectService.getProgettiList(projectFilter.getCur(), projectFilter.getDelta(),
projectFilter.getOrderByCol(), projectFilter.isAsc());
}
}
The order in which the method are invokated is this:
I don't understand why the Model projectFilter doesn't get called, being used as a parameter in the render method. What I see is that Spring prefer to call the constructor of ProjectFilter and setting its fields through setters. How this mapping is done is another matter...
Just to complete and answer to the comment, this project is a portlet deployed in Liferay and it uses using Spring.
The jsp was like this:
<liferay-ui:search-container emptyResultsMessage="No project found"
orderByCol="${projectFilter.orderByCol}" orderByType="${projectFilter.orderByType}"
delta="${projectFilter.delta}">
<liferay-ui:search-container-results total="${progettiCount}"
results="${projectList}">
</liferay-ui:search-container-results>
<liferay-ui:search-container-row
className="it.eng.liferay.portlet.domain.TPrProgetti" keyProperty="id" modelVar="project">
<liferay-ui:search-container-column-text name="Codice" property="codProg" orderable="<%= true %>" orderableProperty="codProg"/>
<liferay-ui:search-container-column-text name="Descrizione" property="descrizione" orderable="<%= true %>" orderableProperty="descrizione"/>
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
I just used one ModelAttribute method that contains every ModelAttribute like this:
@ModelAttribute
public void populateModel(Model model,
@RequestParam(value = "cur", required = false) String curString,
@RequestParam(value = "delta", required = false) String deltaString,
@RequestParam(value = "orderByCol", required = false) String orderByCol,
@RequestParam(value = "orderByType", required = false) String orderByType) {
model.addAttribute("progettiCount", projectService.getProgettiCount());
model.addAttribute("projectFilter", projectFilter);
model.addAttribute("projectList", projectService.getProgettiList(projectFilter.getCur(), projectFilter.getDelta(),
projectFilter.getOrderByCol(), projectFilter.isAsc()));
}
I don't like it very much, but it works.
I tried also using the latest version of Spring that is 4.0.5, but the problem didn't change.