I moved this conversation here from this thread:
Where Ollie said:
This problem seems, to me anyway, to stem from the current implementation of AbstractForm and how it handles a set of editable objects. It simply "swaps out" the underlying domain object being referenced by the value models for the bound controls on the form. Thus, you have to commit one set of changes before you can work on a different object. In essence you have a N:1 mapping from domain objects to form model (inclusive of the value modesl in the bound controls). It would seem that this could be resolved by moving to a N:N model where you create one set of value holders for every object in the editable list. To be honest, I have no idea how hard this would be, but it would preserve the value model in use today and it would remove the "must commit" problem.Given a basic M-D form with one form model for the master form and one form model which allows for editing a single detail item at a time and some logic for switch between which detail item is edited (along the lines of the M-D code you posted on the Wiki).
Now a user comes in and makes some edits to detail item number 1 and then decides to start editing detail item number 2. If we're buffering what do we do with the buffered edits for item 1 at this point? Well, at the moment, you must commit them back to into the item 1 form object or lose them, however once you've commited them back you loose an benefits you gain by using buffering - dirty checking no longer works, you can no longer revert the form etc.
That said, I have always used a cloning model in my middle tier implementations for web apps. Without the whole value model framework to build on, it was the simplest model that provided the ability to back out edits. So, I'm in now way opposed to cloning as the means to achieve the buffering.
In the cloning case, you are moving to a "coarse grained" buffer for the form model - the clone is the buffer for all the bindings on the form. So, if I may guess at the imlpentation you have in mind, you would:
1. Implement the buffering FormModel to create a clone of all domain objects (multiple objects in the case of a M-D form).
2. Bindings created for the form would then reference the currently selected clone directly, using the same access models as now but without buffering. The "current" clone cuold be swapped out just like it does now.
3. The dirty tracking would then be centralized in the form model. Triggering whenever a value is posted (via setValue on the value holder) to the cloned object. This would be necessary since without buffering, the bound value models wouldn't have a meaningful dirty state.
4. Revert operations would simply operate by creating a new clone and replacing the dirty one in the form model.
All of that makes sense (and even seems simpler than the current system), but I see a couple of troublesome areas:
1. How would the application deal with updates to "topmost" domain object in this new system. Currently, since all updates happen through direct property modifications, there is no need for the application to do anything unique when the changes aer committed. The domain object is updated "in situ." However, in the cloning model, there would need to be some method of "replacing" the updated object (since it is a clone that has been changed and not the original). What are your ideas on how to solve this problem? (or am I missing something obvious?)
2. There migt be a performance implication when dealing with large objects. Currently, I can edit a single property on an object of any size (number of properties) in the same time as I can edit one property on a tiny object. Moving to a cloning model would mean that to edit just a single property, I have to clone the entire object. This may not be a significant issue, but I think it bears considering.
3. How drastic would be the changes to the current code base (and code based on it)? I know that compatibility isn't a prime factor given the youth of the platform, but also worth discussing.
4. Probably a few others that I haven't thought of in the last hour of pondering this topic. :wink:
Agreed, being able to leverage the code in the spring core would be a nice benefit.Buffering also makes it impossible to use validation implementations that access the form object directly (implementations of Spring Validator for instance) rather than through a property access strategy.
All in all, this is an intriguing topic and I'm looking forward to the discussion.