Reputation: 338730
The DataProvider::refreshItem
method used by Grid
and other widgets advises two alternate ways for the widget to identify which of the contained items you are trying to refresh:
equals
and hashCode
, identifying the same object reliably without depending on a mutable member field (property).getId
To quote the JavaDoc:
void refreshItem(T item)
Refreshes the given item. This method should be used to inform all DataProviderListeners that an item has been updated or replaced with a new instance.
For this to work properly, the item must either implement
Object.equals(Object)
andObject.hashCode()
to consider both the old and the new item instances to be equal, or alternativelygetId(Object)
should be implemented to return an appropriate identifier.
That last clause above is the tricky part.
➥ My question is: How to implement DataProvider::getId
?
Every example of a DataProvider
I have seen results in a DataProvider being returned by other calls, or internally generated, rather than subclassing. If the normal route to a DataProvider
does not involve subclassing while writing your own implementation, then how does one override getId
to provide an implementation?
Upvotes: 2
Views: 948
Reputation: 725
public class EmployeeDataProvider extends AbstractBackEndDataProvider<Employee, String> {
private static final long serialVersionUID = 1L;
private final EmployeeService employeeService;
public EmployeeDataProvider(EmployeeService employeeService) {
// TODO Auto-generated constructor stub
this.employeeService = employeeService;
}
@Override
protected Stream<Employee> fetchFromBackEnd(Query<Employee, String> query) {
// TODO Auto-generated method stub
return employeeService.fetchEmployees(query.getFilter().orElse(null), query.getLimit(), query.getOffset(),
query.getSortOrders()).stream();
}
@Override
protected int sizeInBackEnd(Query<Employee, String> query) {
// TODO Auto-generated method stub
return employeeService.countEmployees(query.getFilter().orElse(null));
}
@Override
public Object getId(Employee item) {
// TODO Auto-generated method stub
return item.getId();
}
}
You can find working example code here.
Upvotes: 0
Reputation: 8001
You can still create your own data provider sub class if you want to, even though most examples use more convenient factory methods. Extending from AbstractBackEndDataProvider
or ListDataProvider
is usually the best starting point.
Another alternative is to use the three-arguments constructor of CallbackDataProvider
which takes the two regular callbacks as the first two arguments and then a third callback that receives an item and should return an object that can be used as the identifier for that item.
Directly or indirectly overriding getId
is seen as a relatively rarely used feature, so we have chosen to not pollute the top-level DataProvider
interface with factory methods for those cases.
Upvotes: 2