Buffered editable table resetting when adding item

I am having an issue, and i’m sure I’m just going about this the wrong way.

I have a multi user application where people could be looking at the same thing at the same time, but only one will be able to edit.
I am using a BeanContainer to back my table for this specific piece of data, and that data is loaded from the DB into a singleton which has a map filled with my objects. I use that map to fill my bean container the table uses.

I want the user to be able to edit the items in the table, add new items to the table, but for the changes to not take effect until a commit is called. I have this mostly working by using a field factory, and setting the fields to buffered. The only issue is, if I add or remove an item, it clears all the buffered changes that haven’t been committed yet.

The reason I am using buffered fields, is if I don’t, data is changed on the original object instantly without calling a commit.

Is there an easy way to copy the buffered curent value from the old field to the new one when an itemsetchange is triggered on the table? I know at least someone has run across this before, so any pointers would be very helpful.
If code examples would help, let me know and i’ll add them.

Figured out a hackish workaround. I just wanted to post it so if anyone else ran into the same issue, they at least had an idea of where to go.

First I create a class that will help me with field comparisons:

[code]
public class FieldComparison {
private final Object propertyID;
private final Object itemID;

public FieldComparison(Object propertyID, Object itemID) {
    this.propertyID = propertyID;
    this.itemID = itemID;
}

public Object getPropertyID() {
    return propertyID;
}

public Object getItemID() {
    return itemID;
}

@Override
public int hashCode() {
    return propertyID.hashCode() + itemID.hashCode();
}

@Override
public boolean equals(Object obj) {
    try {
        if(this.propertyID == ((FieldComparison)obj).propertyID && this.itemID == ((FieldComparison)obj).itemID)
            return true;
    }
    catch (Exception e) {
    }
    return false;
}

}
[/code]I then create a container to hold all my fields:

    protected Map<FieldComparison, Field> tableFields = new HashMap<>();

After that, I add a listener to every generated field with my fieldfactory:

FieldFactory tableFieldFactory = new FieldFactory() {
            @Override
            public Field createField(final Container container, final Object itemId, final Object propertyId, Component uiContext) {
                Field<?> field = super.createField(container, itemId, propertyId, uiContext);

                if (propertyId.equals("ID")) {
                    field.setReadOnly(true);
                    ((TextField) field).setConverter(new StringToPlainIntegerConverter());
                }
                field.setBuffered(true);
                field.addValueChangeListener(event -> {
                    if (field.isModified() && !tableFields.containsKey(new FieldComparison(propertyId, itemId))) {
                        tableFields.put(new FieldComparison(propertyId, itemId), field);
                    }
                });
                field.addAttachListener(event -> {
                    FieldComparison fieldComparison = new FieldComparison(propertyId, itemId);
                    if(tableFields.containsKey(fieldComparison)) {
                        if(field instanceof TextField)
                            ((TextField) field).setValue((String) tableFields.get(fieldComparison).getValue());
                        if(field instanceof NativeSelect)
                            ((NativeSelect)field).select(tableFields.get(fieldComparison).getValue());
                        if(field instanceof CheckBox)
                            ((CheckBox)field).setValue((Boolean) tableFields.get(fieldComparison).getValue());
                    }
                });
                return field;
            }
        };

As you can see, if a value is changed, the field gets added to the tableFields map. When a new field is attached, we look for an existing field in the tableFieldscontainer for the same propertyId and itemId, and if it exists, we set the value of the newly generated field to be the value of the previously generated field. Once the value is set, the ValueChangeListener is called, and the new field replaces the old one in the tableFieldscontainer.

Not the most elegant solution, but it seems to work pretty well so far.