Data Binding to Multiple Records in Spring (with Velocity)

A client came to me recently asking for modifications to their web application. The application has a many to one relationship; we'll call it the "one" side a Studio, and the "many" side's elements "Films". Updated information for films (box office numbers, tickets sold, etc) comes in batches. Searching, selecting and editing Films one at a time is inefficient, so the client requested batch editing ability.

We started from the user's perspective and decided a spreadsheet-style interface would be most efficient. Users will perform a search to get a list of Films, then edit them in the spreadsheet interface. This required data binding to multiple database records simultaneously.

Here's how I did it in Spring with a Velocity view.

For the most part, the data binding process works the same with multiple records as it does with one. I extended the SimpleFormController, with an implementation that retrieves a List of Films from the data layer in its formBackingObject() method.

That was working fine, so I began to code up the edit form. Here's an excerpt of the first (broken) attempt:


#foreach($film in $command)

#set($index = $velocityCount - 1)

#springBind("command[$index].boxOffice")

#end

That attempt did not work (received an error saying the object command[0] does not exist as an attribute). I scoured the forums and documentation and found no help. Everything seems to check out. I eventually had to look at the Spring source to find out why my code was not working. As it turns out, Spring's data binding assumes that the command object is a simple object (not a List, Map or other Collection). The special List and Map syntax:

#springBind("command.map['key']")

#springBind("command.list[index]")

does not apply the command object itself. Knowing that, I changed my formBackingObject() method to return a command object (call it FilmBatch) that wraps a List of Film objects. I then changed the Velocity template to the following:


#foreach($film in $command.filmList)

#set ($index = $velocityCount - 1)

#springBind("command.filmList[$index].boxOffice")

#end

Reply

The content of this field is kept private and will not be shown publicly.
  • Lines and paragraphs break automatically.

More information about formatting options