Search code examples
javaspringannotationsspring-annotationsmodelattribute

Spring: ModelAttribute doesn't get called


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:

  1. Model projectListCount
  2. Model projectList
  3. Render projectList

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...

EDIT

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>

Solution

  • 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.