Error during Table cache update

Hi,

I got a strange error when I use function setContainerDataSource.
Error is:

My code is:

 table.setContainerDataSource(getDbHelp().getContainer(projectId));

getContainer function:


public SQLContainer getContainer(int projectId) {
  container.removeAllContainerFilters();
  container.addContainerFilter(new Compare.Equal("ProjectId", projectId));
  return container
  }

The container itself:


FreeformQuery myQuery = new FreeformQuery("SELECT * FORM Table", connectionPool, "Id");
MyDelegate myDelegate = new MyDelegate();
myQuery.setDelegate(myDelegate);
container = new SQLContainer(myQuery);

I debugged it and saw that the problem comes from Table.class resetPageBuffer();
It worked fine, but when I added a new row into the table, it doesn’t set a new row as container Data Source. It didn’t work when I had restarted the server also. I don’t know that can be wrong.
Thank you for your help.

Need your help very much.

To debug this, you could try to set a breakpoint in Table.getVisibleCellsNoCache() on all the lines that add something to exceptionsDuringCachePopulation and see what the original problem is.

I found that was wrong. It was caused by this piece of code. Because some of the values in the table had null values.


final Table table = new Table("Formatted Table") {
    @Override
    protected String formatPropertyValue(Object rowId,
            Object colId, Property property) {
        // Format by property type
        if (property.getType() == Float.class) {
            DecimalFormat df =
                new DecimalFormat("#");
            return df.format((Float)property.getValue());
        }
        return super.formatPropertyValue(rowId, colId, property);
    }
};

I added checking.


if (property.getType() == Float.class) {
     DecimalFormat df = new DecimalFormat("#");
     if (property.getValue() == null) {
         return null;
     } else {
         return df.format((Float)property.getValue());
     }
}

Now it works well :slight_smile:

The same error

 com.vaadin.ui.Table$CacheUpdateException: Error during Table cache update

also occurs when you set a NestedContainerProperty (of BeanItemCountainer) as eg: “coutry.name”
and when at the container set a List in which one or more User has getCountry() method that returns a null value
instead of displaying a empty cell, throws the Exception above indicated which has as cause NullPointerException

Yes, and it is a regretion somewhere between 6.8.1 (worked OK) and 6.8.8 (broken).

According to docs, however, all intermediate objects should exists, so probably not a bug.

Regarding intermediate nulls, see
#7229
.

With this issue of nulls in nested property paths, I suggest to use a simple implementation of a ColumnGenerator. It doesn’t require to change your bean classes, and you can use it in all cases where you need to display nested properties in tables. I wrote a NestedPropertyColumnGenerator like this:

 
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.NullValueInNestedPathException;

import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.ColumnGenerator;

public class NestedPropertyColumnGenerator implements ColumnGenerator {

	private String nestedProperty;
	
	public NestedPropertyColumnGenerator(String nestedProperty) {
		this.nestedProperty = nestedProperty;
	}

	@Override
	public Object generateCell(Table source, Object itemId, Object columnId) {
		BeanWrapperImpl beanWrapper = new BeanWrapperImpl(((BeanItem)source.getItem(itemId)).getBean());
		try {
			return beanWrapper.getPropertyValue(nestedProperty);
		} catch (NullValueInNestedPathException nvnpe) {
			return "";
		}
	}
}

In the example above, you can then use the ColumnGenerator like this:

table.addGeneratedColumn("countryname", new NestedPropertyColumnGenerator("country.name"));

Note it uses a reflection utility class from the Spring framework, so if you don’t use Spring in your project, it will be necessary to use a different reflection mechanism.

if exist a Set property, the table will not correct display,throw exception"Error during Table cache update",.

I can:

private Table gTable = new Table(“caption”) {
@Override
protected String formatPropertyValue(Object rowId, Object colId,
Property property) {
if (property.getType() == Set.class) {
return null;
}
return super.formatPropertyValue(rowId, colId, property);
}
};

it work well.

Karolis Valiulis:
I found that was wrong. It was caused by this piece of code. Because some of the values in the table had null values.

final Table table = new Table("Formatted Table") {
    @Override
    protected String formatPropertyValue(Object rowId,
            Object colId, Property property) {
        // Format by property type
        if (property.getType() == Float.class) {
            DecimalFormat df =
                new DecimalFormat("#");
            return df.format((Float)property.getValue());
        }
        return super.formatPropertyValue(rowId, colId, property);
    }
};

I added checking.

if (property.getType() == Float.class) {
     DecimalFormat df = new DecimalFormat("#");
     if (property.getValue() == null) {
         return null;
     } else {
         return df.format((Float)property.getValue());
     }
}

Now it works well :slight_smile:

Nice, it works also for me))