Tuesday, April 14, 2009

Maintain the order of List in Spring Bind

In most cases, one-to-many is mapped as Set in Hibernate. Set is not ordered. If a domain object has Set, Set is converted to List in DTO to bind it with Spring. If that's the case, it is very important to maintain the order. Here is a use case. A Spring form controller is set to sessionForm= false and the DTO is read in formBackingObject().

  1. A user comes to the form the first time. formBackingObject() is called. Domain object is read. DTO is created. Set is converted to List.
  2. Form is rendered. Elemenets in List is created in HTML.
  3. User fills out data and submits.
  4. Since sessionForm is false, formBackingObject() is called again BEFORE onSubmit(). Again, Domain object is read. DTO is created. Set is converted to List. However, please note that when the domain object is read this time, the order of elements in Set could be different from Step 1. Then the order of elements in List is different the ones in Step 1.
  5. Binder.bind() happens. Bind is still binding the List data according to the order in Step 1. But the actual order of List data is as in Step 4. This means that the binding binds the data of 1st element to that of the 3rd element, for example.
  6. Now it comes to onSubmit(). The DTO's list data has the wrong binding. Once this data is processed at the service/DAO, it could run into all kinds of errors/bugs.

To fix this problem, we need to avoid the seond reading in Step 4. This can be done by setting sessionForm=true. Or if it has to be read, we can add "sort" or "order by" in Hibernate mapping for the Set to force it to maintain a consistent order.

No comments:

Post a Comment