Results 1 to 7 of 7

Thread: What order are annotated methods called in?

  1. #1
    Join Date
    Aug 2004
    Location
    Denver
    Posts
    249

    Default What order are annotated methods called in?

    In a Spring 2.5 Controller, I have a couple methods that have annotations. One has:

    @RequestMapping(method = RequestMethod.GET)

    And the other has:

    @ModelAttribute("countries")

    Is it documented anywhere what order these annotations/methods will be called? I thought @RequestMapping would be called first, but it turns out that @ModelAttribute methods are called first.

    Thanks,

    Matt

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,632

    Default

    Is it documented anywhere what order these annotations/methods will be called? I thought @RequestMapping would be called first, but it turns out that @ModelAttribute methods are called first.
    Order isn't documented, couldn't find anything in the reference guide nor the javadocs. I'll post a JIRA issue on the issue.

    ModelAttribute would go before RequestMapping IF specified as a attribute. If specified on a method I would expect it to go after the RequestMapping. At least if they would follow the command object and reference data example/explaination they use.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Aug 2004
    Location
    Linz, Austria
    Posts
    391

    Default

    @ModelAttribute-annotated methods will be executed before the chosen @RequestMapping-annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database. Those attributes can then already be accessed through @ModelAttribute-annotated handler method parameters in the chosen handler method.

    In the case of @ModelAttribute used at the handler method parameter level, they will be evaluated after the @RequestMapping-annotated handler method has been chosen - but of course before that handler method will be invoked (since those attributes are used as method arguments).

    Juergen

  4. #4
    Join Date
    Sep 2004
    Location
    Melbourne, Australia
    Posts
    36

    Default Annotated controller lifecycle

    I'm looking at this now if what I understand you're saying is correct Juergen, i'm not getting this behaviour.

    I'm finding that the order of methods called with the @ModelAttribute is not effected by anything, whether the annotation is method or argument based.

    I have the following methods all annotated with @ModelAttribute. The getOrganisations(...) and getRoles(...) methods require the bound return value from getSaveUserRequest(...) so that they can determine the correct values for the lists. I had hoped that using the @ModelAttribute("user") annotation at the method arg level would have forced the required order of these methods being called and passed the result of the getSaveUserRequest() method but it doesn't seem to be the case.

    Previously I would have returned the saveUserRequest using formBackingObject and the reference data lists would have been setup in the referenceData() method. The lifecycle under SimpleFormController was very straight forward for this as formBackingObject always went off before referenceData(). I can't see any way to guarantee the order with the ModelAttribute annotation approach.

    Any ideas ??

    Code:
        @ModelAttribute("user")
        public SaveUserRequest getSaveUserRequest(@RequestParam(value = "id", required = false)
        Long id) {
    
            if (id != null) {
                final UserDetails userDetails = administrationApplication.findUserById(id);
                return convertToSaveUserRequest(userDetails);
            } else {
                final SaveUserRequest saveUserRequest = new SaveUserRequest();
                saveUserRequest.setUserType(administrationApplication.getCurrentAuthenticatedUser().getUserType());
                return saveUserRequest;
            }
    
        }
        
        @ModelAttribute("roles")
        public List<RoleDetails> getRoles(@ModelAttribute("user") SaveUserRequest saveUserRequest) {
    
            if (saveUserRequest.isVendorUser()) {
                return administrationApplication.findAllVendorRoles();
            } else if (saveUserRequest.isClientUser()) {
                return administrationApplication.findAllClientRoles();
            } else {
                return new ArrayList<RoleDetails>();
            }
    
        }
    
        @SuppressWarnings("unchecked")
        @ModelAttribute("userTypes")
        public List<UserType> getUserTypes() {
            return CollectionUtils.arrayToList(UserType.values());
        }
    
        @ModelAttribute("organisations")
        public List<OrganisationDetails> getOrganisations(@ModelAttribute("user") SaveUserRequest saveUserRequest) {
    
            if (saveUserRequest.isVendorUser()) {
                return administrationApplication.findAllVendorOrganisations();
            } else if (saveUserRequest.isClientUser()) {
                return administrationApplication.findAllClientOrganisations();
            } else {
                return new ArrayList<OrganisationDetails>();
            }
    
        }
    Something else that concerns me is that where the referenceData() method in SimpleFormController goes off only as part of calling showForm meaning it will go off when the form is setup for a GET and also following failed validation, it appears that the @ModelAttribute annotated methods will go off more often and not always at the required times.

    Am I missing ,the point with some of this ?

    cheers,
    rob

  5. #5
    Join Date
    May 2007
    Posts
    29

    Default @ModelAttribute Dependency

    The post above poses the scenario where we might want to have dependent @ModelAttribute annotated methods.

    @ModelAttribute("foo")
    public Object getFoo() {
    ...}

    @ModelAttribute("Bar")
    public object getBar(@ModelAttribute("foo")) {
    ...
    }

    I mistakenly thought that the execution order would be based on dependencies, but this only appears to work for @RequestMapping -> @ModelAttribute dependencies.

    It seems like this would be a common use case - especially where you might want to provide alternate representations of an object that's loaded from the DB - to keep things in the view simple.

    I fully expect there might be a really good reason this is not supported - I would be grateful if anybody has more information on this.

    I looked in Jira but didn't see any outstanding enhancements for this.

    Thanks,

    -Troy

  6. #6
    Join Date
    Dec 2006
    Posts
    2

    Default RE: @ModelAttribute Dependency

    Any update on this since Jan of 2009? I have this exact use case.

    This thread is a top hit in Google, it would be a great place to post any advances in this area. I know I will post if I find anything that solves the dependent @ModelAttribute problem.

  7. #7
    Join Date
    Mar 2006
    Posts
    312

    Default

    I've created a JIRA (SPR-6299) for this.

    http://jira.springframework.org/browse/SPR-6299

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •