views:

1827

answers:

1

Under what exact circumstances do @SessionAttributes get cleared? I've discovered some confusing behaviour when trying to use two models in a page.

When I do a GET followed by a POST using this controller...

@Controller
@RequestMapping("/myPage*")
@SessionAttributes(value = {"object1", "object2"})
public class MyController {

  @RequestMapping(method = RequestMethod.GET)
  public String get(Model model) {
      model.addAttribute("object1", new Object1());
      model.addAttribute("object2", new Object2());
      return "myPage";
  }

  @RequestMapping(method = RequestMethod.POST)
  public String post(@ModelAttribute(value = "object1") Object1 object1) {
      //do something with object1
      return "myPage";
  }
}

...object2 gets cleared from the Model. It no longer exists as a @SessionAttribute and cannot be accessed on my view page.

However if the signature of the second method is modified to this...

public String post(@ModelAttribute(value = "object1") Object1 object1,
                   @ModelAttribute(value = "object2") Object2 object2) {

...then object2 does not get cleared from the model and is available on my view page.

The javadoc for @SessionAttributes says:

... attributes will be removed once the handler indicates completion of its conversational session.

But I don't see how I have indicated completion of the conversational session in the first example but not in the second example.

Can anyone explain this behaviour or is it a bug?

+2  A: 

You indicate completion of the conversation by calling

SessionStatus.setComplete

public void post(...., SessionStatus status) {
  status.setComplete();
}

That said, I don't see why you should be loosing one model attribute and not the other.

Have you tried doing something like:

@ModelAttribute("object1")
public Object object1() { return new Object(); }

@ModelAttribute("object2")
public Object object2() { return new Object(); }

And see how that compares to putting the attributes in the model by hand.

ptomli
I tried your suggestion - and amazingly it works! Now I'm really confused. Why is there a difference to setting the model attribute manually and setting it using @ModelAttribute?
Daniel Alexiuc
Alas I made a boo-boo. From the reference (3.0.0.M3): "Note: @ModelAttribute annotated methods will be executed before the chosen @RequestMapping annotated handler method". So the reason that works is that the object1 and object2 methods are executed before both the get and post methods. This may actually be what you want, but I suspect not.
ptomli
Yes I realised that just after I posted my comment. I might raise this with Spring as I don't see any reasonable explanation for this behaviour.
Daniel Alexiuc
This Issue has been raised with Spring: http://jira.springframework.org/browse/SPR-6084
Daniel Alexiuc
This issue has now been resolved in Spring 3.0RC1. Thanks Juergen!
Daniel Alexiuc