0

I'm developing a new Spring MVC application using RESTful requests. The application does the standard database load object, bind values and save. In order to not lose object values which are not available on the form, I'm using a @ModelAttribute method to preload the object prior to binding.

When loading an agency using the URL

/agency/418

my @ModelAttribute method has now way of learning of the '418' ID. My understanding is that only regular request attributes can be processed, so my URL would need to be

/agency/418?id=418

which kinda breaks the RESTful pattern. Same thing when POSTing data.

Could someone comment on this observation ... am I missing something?

Thanks Simon

Simon
  • 2,994
  • 3
  • 28
  • 37
  • My comment would be that you are trying to use the ModelAttribute function for something it was not meant to do. It was not meant to pre-populate objects for use in RESTful service calls, it was meant to ease binding between form data and the controller. That data would be either POST'ed or GET'ed, you in that sense you are correct, you would have to pass in the values in order to do what you are trying, but I think your milage will vary. – CodeChimp Mar 01 '13 at 19:29
  • http://stackoverflow.com/questions/3672100/spring-mvc-3-0-how-do-i-bind-to-a-persistent-object suggests to use a form object for binding ... I'll look into that. – Simon Mar 05 '13 at 09:54
  • There are two places you can put the ModelAttribute annotation. The first is on a parameter of a view handler method. In this case the use is to provide binding between the form and the handler. The second is to put it on a method that takes no arguments and returns a new instance of the target ModelAttribute. This is typically a private method. The purpose of this is to create a default version when a handler defines a ModelAttribute that isn't in the Model or the HttpSession. This method is then called to create an empty, initialized instance for use by the view handler method. – CodeChimp Mar 05 '13 at 14:14
  • If you want to handle a RESTful request, where the values are passed as part of the URL, I would suggest looking at the PathVariable annotation, which allows you to bind a parameter of your handler to an part of the incomming URL pattern. @Martin Frey has a nice example down below. – CodeChimp Mar 05 '13 at 14:15

2 Answers2

1

You can very well use a pathvariable to initialze a modelattribute:

@controller
public controller {
   @modelattribute("model")
   public Entity initentity(@pathvariable integer id) {
     return dao.getentity(id);
   }

   @requestmapping("/{id}")
   public String somerequest(@modelattribute("model") Entity entity) {
      ....
   }      
}
Martin Frey
  • 10,025
  • 4
  • 25
  • 30
  • I believe https://jira.springsource.org/browse/SPR-5500 covers the topic accurately. – Simon Mar 04 '13 at 14:01
  • Thats a good pointer. We ran into this issue and solved it with separating controllers the way its described in the second comment. Its a clean solution from my point of view. – Martin Frey Mar 07 '13 at 06:07
0

We gave up on the idea of using @ModelAttribute to replace what used to be "formBackingObject" in Spring 2. Instead, we're using plain form object classes for form binding, and then copying over the values to the persistent entity. The form object can be created on-the-fly by Spring, thus we don't require a @ModelAttribute with database load anymore. The topic is covered in Does Spring MVC require copy/paste of Entity to FormObject?.

Community
  • 1
  • 1
Simon
  • 2,994
  • 3
  • 28
  • 37