Grid won't refresh with JPA associated data

I’m not sure if anyone have experienced this problem. I have a grid with persistence data from two tables (user and role) with OneToMany and ManyToOne annotation. I used the form with combobox to make static selection of user’s role and the dataprovider correctly showed updated role id number after the refreshAll call but it showed the old role’s name in the grid. I’m not sure why this is happening but other data like textfield showed the changes correctly except for the role’s name. However, when I do a hard refresh using the refresh button on the browser and it showed the updated role’s name in the grid correctly.

I have this function user.getRole().getName() which is in user.class to fetch the role’s name from role.class. This function user.getRoleId() which is in user.class showed the correct id but user.getRole().getName() returned the old name until I do the hard refresh. I’m not sure why this is happening. Any ideas?

Hi,

Did you implement equals in your entity?

https://vaadin.com/forum/thread/15586695

The dataprovider need to know the entity to refresh and is using equals.

Yes I already included the equals and hashcode in the entity class. It still won’t update the grid with selected role’s name. It will update the grid after hard refresh or pushed save button twice.

I think I found the problem. The update works perfectly by updating the database but it doesn’t update the dataprovider or grid correctly. I did some workarounds by reload using findAll and dataprovider to get it working but is there a better way to do this? Here’s my “save” button code. BTW, I’m using Vaadin 14.

emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
em = emf.createEntityManager();
UserService userService = new UserService(em);
em.getTransaction().begin();
User user = userService.findUser(userTemp.getId());
user.setUserName(txtUserName.getValue());
user.setFirstName(txtFirstName.getValue());
user.setLastName(txtLastName.getValue());
user.setPassword(txtPassword1.getValue());
Role trole = cmbRole.getValue();
user.setRoleId(trole.getId());
user.setRole(trole);
			
if (imageTemp != null) {
	user.setImage(imageTemp);
	image.getElement().setAttribute("src", new StreamResource("", () -> new ByteArrayInputStream(user.getImage())));
}
em.persist(user);
em.getTransaction().commit();

users = userService.findAll();
dataProvider = new ListDataProvider<>(users);
grid.setDataProvider(dataProvider);
grid.getDataProvider().refreshItem(user);
		    
em.close();
emf.close();

You don’t need to do that:

users = userService.findAll();

But you need to refresh at least the updated user in the list and call refreshItem(user);.

But it’s probably easier to refreshed the list from the database (in case other users have been updated).

Jean-Christophe Gueriaud:
You don’t need to do that:

users = userService.findAll();

But you need to refresh at least the updated user in the list and call refreshItem(user);.

But it’s probably easier to refreshed the list from the database (in case other users have been updated).

I made major changes to my code and was able to get it working and the codes are much cleaner now. I plan to implement a runnable thread or polling to check the database for any changes in the near future.