Table Selection not updated when container is updated

Hello there,

I am struggling while trying to update a BeanItemContainer backing a Table with a user selection.

This is my use case (please see the attached 2 files):

  • Server
    [list]
  • Create a Table, backed by a BeanItemContainer.
  • Put an item into the beanItemContainer.

    [/list]
  • User
    [list]
  • Select the item in the table
  • Click “update container”

    [/list]
  • Server
    [list]
  • replace the item in the BeanItemContainer with an updated version being “equal” to the old one
    (This simulates someone else updating Entities in the database. The equals method just takes the primary key into account.)

    [/list]
  • User
    [list]
  • Click “show item data”

    [/list]
  • Server
    [list]
  • display
    (a) item data from BeanItemContainer
    (b) item data from table selection (Table.getValue())

    [/list]


My expectation
: (a) and (b) should be both up to date and the same (object identity)

Result

  • the item from BeanItemContainer (a) has the changed (updated) item
  • the item from Table (b) still has the old (unchanged) item
  • they are NOT the same but equal

Isn’t Vaadin supposed to update the table selection when the backing container is updated?

What is the easiest possibility to fix this problem?

Thanks a lot,
Sascha
11990.java (2.88 KB)
11991.java (1.3 KB)

Did you figure it out? And please tell if you found some great way to do it :slight_smile:

I think updating the actual item instead of replacing it would be a good place to start, but if that’s not possible I think you might need to just set the table value again. I doubt (do correct me if I’m wrong) the equals matters outside the moment when the table selects the item, after that it just points to an object and that object isn’t the one you wish it to be.

No, I didn’t.

I had to add a really nasty hack to make that work:
Implement an ItemSetChangeListener which is added to the table.

final class UpdateTableSelectionOnItemSetChange<M> implements ItemSetChangeListener {
	private final Table table;

	UpdateTableSelectionOnItemSetChange(final Table table) {
		super();
		this.table = table;
	}

	@SuppressWarnings({ "PMD.SimplifyConditional", "rawtypes", "unchecked" })
	@Override
	public void containerItemSetChange(final ItemSetChangeEvent event) {
		final Collection<M> itemIds = (Collection<M>)table.getContainerDataSource().getItemIds();
		if (itemIds.isEmpty()) {
			// a previously filled table is now empty ==> remove its value since its selection is outdated this also
			// updates dependent forms via a resulting value change event
			table.setValue(null);
		} else {
			final Object tableVal = table.getValue();
			if (tableVal instanceof Collection && tableVal != null && !((Collection)tableVal).isEmpty()) {
				final M selectedItemId = ((Collection<M>)tableVal).iterator().next();
				// FIXME: needs to be adapted for multiselect tables

				for (final M itemId : itemIds) {
					if (itemId.equals(selectedItemId) && itemId != selectedItemId) {
						table.setValue(null); // otherwise the next set value will be discarded since
												// oldVal.equals(newVal)
						table.setValue(Collections.singleton(itemId));
						break;
					}
				}
			}
		}
	}
}

I hope this helps others…

Do you think we should file a bug?

Might be worth a shot, yes. I can see how that would be a useful feature for other users as well - and thanks for sharing your solution! Even nasty hacks can be useful :slight_smile: Your solution is actually pretty close to what I was thinking about, but an example is always better. Anyway, I’m not sure how easy fix that would be, so better not count on it getting solved in near future. Generally speaking Table is the difficult one, so it might take a good while. Unless the problem is with BeanItemContainer itself, of course. I haven’t used that one much so I really can’t say. Have you tried other containers? SQLContainer might be worth checking out, unless you’ve already done so, and of course there are plenty of containers in add-ons, too. I’ve mostly dealt with JPAContainer lately, and JPA itself really has been an experience to get to know :slight_smile:

So did you create the bug?

Because I think I stepped into this or something similar and reported it as
#10993
. No reply yet… I solved it by resetting the selection every time the container is modified.