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