Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Grid not showing data from bound BeanItemContainer after update to 7.6.1
Hi there,
I updated my application from version 7.5.9 to 7.6.1 and non of my Grids are showing any data anymore. Checked it, but data is retrieved from backend and the BeanItemContainer, containing the data, is set as a datasource correctly. It just doesn't show up. Thankful for any suggestions.
Cheers
Hi,
There were some regressions between 7.5 and 7.6 regarding Grid. If the problems are still present with 7.6.2 it's most likely a previously unknown regression. If you can post a test UI where we can see this issue (as much vanilla vaadin as possible) it will speed up the fixing process.
Hope to hear from you soon so we can fix this issue.
//Teemu
Well. Tested it with version 7.6.2 and no luck. What exactly do you need to track this bug down? I'm afraid I can not post the whole code, because it is quite a lot and I am bound to secrecy. But I post as much as I can to help out.
If you can build a vanilla vaadin UI with a minimal setup that causes the same problem, that's the best situation. If you can't implement a UI that fails in the same way, then we need to take a closer look to see if we can find something out of place. The latter one is going to take some, since we at the framework team are really busy right now.
Still no luck. If there is anything else I can do to help, let me know!
Hi,
Do you have equals and hashCode implemented in your BeanItems and if so how?
After upgrading to 7.6.x I had the problem that updates to a simple Bean (like Person below) were not sent to the client side anymore. Although I removed the old person object from the container and added the changed but the id stayed the same and therefore equals too.
Person {
private Long id;
private Date updatedAt;
private String firstname;
private String lastname;
public boolean equals(Object o) {
return o.id.equals(id);
}
// hashcode was implemented too
}
I had to include id and updatedAt in the equals to keep Grid working as it was in 7.5.10.
I hope to test this behavior in a simple Vaadin app like Teemu suggested as well.
This is not exactly your use case but it might helps narrowing down the problem.
Cheers,
Michael
Michael Oberwasserlechner: Hi,
Do you have equals and hashCode implemented in your BeanItems and if so how?
After upgrading to 7.6.x I had the problem that updates to a simple Bean (like Person below) were not sent to the client side anymore. Although I removed the old person object from the container and added the changed but the id stayed the same and therefore equals too.
Person { private Long id; private Date updatedAt; private String firstname; private String lastname; public boolean equals(Object o) { return o.id.equals(id); } // hashcode was implemented too }
I had to include id and updatedAt in the equals to keep Grid working as it was in 7.5.10.
I hope to test this behavior in a simple Vaadin app like Teemu suggested as well.
This is not exactly your use case but it might helps narrowing down the problem.
Cheers,
Michael
Thanks Michael,
I do not have hashCode and equals implemented in my BeanItem, but I noticed the behavior you described at another point in my application. There I deleted the hashCode and equals methods to get it working.
Questions at Teemu: Is it nescessary to implement hashCode and equals into my BeanItems for Grid to work properly.
Thanks again and have a great day
Just the quick update. Issue is still not resolved with Vaadin 7.6.3
I'm also having the same issue and have stripped the grid code down to almost nothing. I would send a sample but it's through a few hierarchies. That being said it is stripped down to nothing.
In debug mode I can confirm that the container for the grid does contain data (and the correct data), however it just won't display any data on the screen.
I updated from 7.5.2 to 7.6.3 in one step.
Stephan Grenier: I'm also having the same issue and have stripped the grid code down to almost nothing. I would send a sample but it's through a few hierarchies. That being said it is stripped down to nothing.
In debug mode I can confirm that the container for the grid does contain data (and the correct data), however it just won't display any data on the screen.
I updated from 7.5.2 to 7.6.3 in one step.
This is true for all the tables, it's just not just isolated to a specific table.
I've created a sample View with just the code bare code from the sample in the documentation. Below is the class file. Viewing this in the browser results in the grid showing up but it is completely empty of data.
PS I overwrote the equals and hashcode methods because the documentation said this was required. I used the default Eclipse source generation code.
package test.mypackage;
import java.io.Serializable;
import java.util.Collection;
import com.google.common.collect.Lists;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;
public class TestView extends VerticalLayout implements View
{
public TestView()
{
setSizeFull();
Collection<Person> people = Lists.newArrayList(
new Person("Nicolaus Copernicus", 1543),
new Person("Galileo Galilei", 1564),
new Person("Johannes Kepler", 1571));
// Have a container of some type to contain the data
BeanItemContainer<Person> container =
new BeanItemContainer<Person>(Person.class, people);
// Create a grid bound to the container
Grid grid = new Grid(container);
grid.setColumnOrder("name", "born");
addComponent(grid);
}
@Override
public void enter(ViewChangeEvent event)
{
}
}
class Person implements Serializable
{
String name;
int born;
public Person(String name, int born)
{
this.name = name;
this.born = born;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getBorn()
{
return born;
}
public void setBorn(int born)
{
this.born = born;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + born;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (born != other.born)
return false;
if (name == null)
{
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
I've been testing for a while now, several hours (I started way before posting here). And through trial and error I think it has to do with some kind of cache mechanism.
I say this because I initially moved that code to a View which I added through addComponent in the UI and it failed. I then put that code in the UI directly and it worked. Well mostly. Then when I tried to move it back I started to get some weird serialization errors. I did full tomcat cleans, tomcat working directory clean, widget and theme compile, and project clean, and then the next thing I know it started to work in the View code rather than directly in the UI. Exact same code that was failing before and resulting in an empty table. The problem is that before there was no error or exception in the console.
Weird...
In any case this leads me to believe it's something cache related, that's not being correctly cleaned. My next step is going to be to do delete the project and re-check it out. If that resolves the issue I'll let you know. Otherwise I'm running out of ideas. For sure it's not code related. That code works in one place then when I move it up the hierarchy it has an empty table with no errors. Then I clean everything, it works. Push it to the next level and same issue. One level at a time I'm able to make it work...
It has to be some kind of caching issue because I completely deleted the project, re-checked it out from the code repository, and ran it. Right away I got a InvalidClassException on the main UI class: "local class incompatible: stream classdesc serialVersionUID" followed by the serialID etc.
I still haven't found a resolution but I'm trying to work through it.
Success !!!
The issue is some kind of caching issue with Tomcat. No matter what I did Tomcat was caching something.
To resolve the issue I updated to the latest version of Tomcat, from 8.0.24 to 8.0.32 and without doing anything else everything just started to work as expected. No issues at all. Every single view worked perfectly. No class serialization errors.
Therefore this leads me to believe there is something in Tomcat that is not cleared out when you upgrade. I don't know what, I cleaned everything I could think of. I even manually went to Tomcat's work directory and couldn't see anything.
Just a very weird bug. But at least there is now a solution. Hopefully that will fix the issue for you Dirk. And if it does then hopefully that gives you the ability to reproduce it Teemu. It's the weirdest thing ever...
Hi Stephan,
thanks for your effort you put into "solving" this problem. Didn't had time to check if this works in my case, but will try asap. I'm using Glassfish 3.1 and I'm bound to it due to project restrictions. Tried it on Glassfish 4 but same problem there. Maybe fresh install and fresh new domain will help.
Hi Dirk,
You're welcome. And to be quite honest I had to solve it for myself too. There was definitely some weird caching issue going on and a fresh install cleaned everything up. For all I know it could be somewhere in the eclipse plugin. Part of upgrading Tomcat versions is that I had to add/remove the servers in eclipse. In any case there was some weird caching issue going on which I never tracked down. And to be completely honest, I wasn't all that interested in tracking it down because I've never had any prior issues with upgrading so I'm pretty confident it's a one time issue.
Good luck with the fresh install and domain.
Hi,
There's a known problem with Eclipse + IVY when updating to a newer version. For some reason the ivy resolve does not resolve the vaadin-client package, which is needed to compile the widgetset. Even though you've recompiled it, it might've still used the old vaadin-client. The issue is easily fixed by running Ivy > Reload settings for the project, but even then it's not always updating correctly. Are you using ivy as the dependency management?
//Teemu
I'm using Ivy to update the Vaadin references so that could definitely explain it for me...
I found that browsers look for old .cache.js files after Vaadin upgrades. That was a minor nusiance for desktop UIs, but a showstopper for Touchkit UIs, where the cache could not be cleared. The somewhat desperate solution below based on a do Filter completely fixed it for me.
I haven't tried removing the doFilter since Tomcat 8.0.32. If there are any other ideas as to how to handle this or if it is now known to be an old problem I'd be happy to revist.
I use Ivy too and the "Clean all caches", "Resolve" pair is used on every upgrade but doesn't solve this problem.
package ca.demy.commonservlets;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ca.demy.core.CommonConstants;
/*
* This is a workaround for a bad behaviour between iOS and TouchKitServlet where
* after rebuilding the widgetset an iOS device that has the webapp set as a Home Screen
* icon continues to refer to the cached .cache.js files instead of asking for new ones.
*
* It also avoids a problem that occurs in Eclipse after upgrading Vaadin, rebuilding dependencies
* and re-compiling the widgetsets - that problem being that the browser looks for the
* previous rather than the current widgetset .cache.js files.
*
* The concept of a servlet filter is explained here: http://tutorials.jenkov.com/java-servlets/servlet-filters.html
* The idea behind this filter was seeded from this thread: https://vaadin.com/forum#!/thread/9940804/9957413
*
* There is an entry in web.xml which intercepts any request for a url that ends in .js and sends it here
*
* We're looking for any reference to a mobile widgetset javascript file. It would have this form and be the result
* of a mobile widgetset compilation: F105D1FA987853D3D4A74D66FBC9A59C.cache.js
*
* So this filter initially looks for 3 conditions
* 1) That the request is for a mobile as opposed to the main widgetset
* [EDIT] There is now an implementation for requests for desktop UIs too.
* 2) That the request contains a reference to a [xxx].cache.js file
* 3) That the request is for an out of date file
*
* Then the doFilter substitutes requests for the old .cache.js file with the new one
* either in the deferredjs folder or in reference to the [xxx].cache.js file
*
*/
@WebFilter(
asyncSupported = true,
filterName = "oldWidgetsetWorkaroundFilter",
urlPatterns = {"*.js"}
)
public class OldWidgetsetRedirect implements Filter {
// identify the widgetset folders as they would appear in a request from a phone
// Also identify folder name where some of the target files are located, and the target file suffix
String mobileWidgetsetName = "/VAADIN/widgetsets/ca.demy.widgetset.FossMobileWidgetset/";
String desktopWidgetsetName = "/VAADIN/widgetsets/ca.demy.widgetset.FossWidgetset/";
String deferredjsFolderName = "deferredjs";
String targetFileSuffix = ".cache.js";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Logger filterstart = Logger.getLogger("filterstart");
filterstart.info("*** FleetCaptain *** The doFilters have been started");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
// the URI requested by the device
String requestURI = ((HttpServletRequest) request).getRequestURI();
if ( requestURI.contains(targetFileSuffix) ) {
// this string will be replaced with the file name that is the character set we're looking for
// use "initial string" rather than "" to avoid any unintentional false matches
String jsStringMobile = "initial string";
String jsStringDesktop = "initial string";
// this automatically finds the file containing the code string we want and assigns it to jsString
if ( CommonConstants.BASEPATH != null ) {
File[] mobilefiles = new File(CommonConstants.BASEPATH + mobileWidgetsetName + deferredjsFolderName ).listFiles();
File[] desktopfiles = new File(CommonConstants.BASEPATH + desktopWidgetsetName + deferredjsFolderName ).listFiles();
for ( File file : mobilefiles ) { // there should only be one
jsStringMobile = file.getName();
}
for ( File file : desktopfiles ) { // there should only be one
jsStringDesktop = file.getName();
}
}
// if the request is not for the current mobile widgetset id string
if ( !requestURI.contains(jsStringMobile) && requestURI.contains(mobileWidgetsetName) ) {
replaceOldWidgetSetReferenceWithNew(response, requestURI, mobileWidgetsetName, jsStringMobile);
// if the request is not for the current desktop widgetset id string
} else if ( !requestURI.contains(jsStringDesktop) && requestURI.contains(desktopWidgetsetName) ) {
replaceOldWidgetSetReferenceWithNew(response, requestURI, desktopWidgetsetName, jsStringDesktop);
// if there is no change to be made, just pass the request along
} else {
filterChain.doFilter(request, response);
}
} else {
filterChain.doFilter(request, response);
}
}
private void replaceOldWidgetSetReferenceWithNew(ServletResponse response, String requestURI, String widgetsetName, String jsString) throws IOException, ServletException {
((HttpServletResponse) response).setContentType("application/javascript");
// replace requests for old files in the deferredjs folder with references to the new one
if (requestURI.contains(deferredjsFolderName)){
String toReplace = requestURI.substring(requestURI.indexOf(deferredjsFolderName + "/") + deferredjsFolderName.length() + 1, requestURI.lastIndexOf("/"));
String newURI = requestURI.replace(toReplace, jsString);
((HttpServletResponse) response).sendRedirect(newURI);
// replace requests for the old [xxx].cache.js with a reference to the current one
} else {
String toReplace = requestURI.substring(requestURI.indexOf(widgetsetName) + widgetsetName.length(), requestURI.lastIndexOf(targetFileSuffix));
String newURI = requestURI.replace(toReplace, jsString);
((HttpServletResponse) response).sendRedirect(newURI);
}
}
@Override
public void destroy() {
Logger filterstop = Logger.getLogger("filterstop");
filterstop.info("*** FleetCaptain *** The doFilters have been stopped");
}
}