views:

2355

answers:

2

Hello,

Without thinking about it too much, I've been doing something like the following:

1) building a list of SomeBean objects based on the results of a database call

2) putting that list in my command object

3) building a form based on that command object where users can modify attributes of the SomeBeans

4) extracting data out of the post-submit command object and writing the updated data to my database

My code looks something like this:

public class UpdateThingsinListController extends SimpleFormController {

 protected Object formBackingObject(final HttpServletRequest request)
    throws Exception {

 List<SomeBean> beans = database.getBeans();

 Command comamnd = new UpdateThingsCommand()
 command.setList(beans);

 return command;

  }

   protected ModelAndView onSubmit(final HttpServletRequest request,
    final HttpServletResponse response, final Object commandArg,
    final BindException errors) throws Exception {

 database.setBeans(commandArg.getList());       

   }


}

my jsp looks somthething like:

<form:form>
 <c:forEach var="bean" items="${beans}" varStatus="status">
  <form:checkbox path="beans[${status.index}].someBooleanProperty" />${bean.name} <br> 
 </c:forEach>
</form:form>

The code works fine, but it's just dawned on me that my "beans" list is getting created twice (sessionform must be false in my case) -- once when displaying the form, once when binding. If anything changes on the second creation (a bean is missing, the results are in a different order), my binding will get messed up, and I'll get fired. I'm beginning to think that any biding scheme where a command object needs to be merged with a form submission is very risky.

So, my question is -- how do folks ensure that form submissions get bound to lists correctly? Is there another way to do it besides list index? Object ids maybe?

thanks,

-Morgan

A: 

The quick way is to first delete all existing SomeBeans from the database and create the ones bound on submit.

A more elegant way might be to put the unique identifier of the SomeBean in a hidden form field.

Kees de Kooter
A: 

If you can't depend on the List always being the same whenever you retrieve it, then you have to use a different collection - a map.

Another approach would be to cache your List somewhere. Perhaps some AOP around your database.getBeans method.

bpapa