|
|
TableModelService
TableModelService
TableModelService is a service interface that provides data for displaying in a GWT AdvancedTable widget. The implementing class should provide paging, filtering and sorting as this interface specifies.
Source Code
public interface TableModelService extends RemoteService {
public TableColumn[] getColumns();
public int getRowsCount(DataFilter[] filters);
public String[][] getRows(int startRow, int rowsCount,
DataFilter[] filters, String sortColumn, boolean sortOrder);
}Lifecycle
1) getColumns() is called by the client to populate the table columns
2) getRowsCount() is called by the client to estimate the number of available records on the server.
3) getRows() is called by the client to display a particular page (a subset of the available data)
The client call getRowsCount() and getRows() with the same filter. The implementing class can use database or other back-end as data source.
Sign in to add a comment

This is a sample source code that you can use to bind the table to Hibernate:
// This is the Hibernate session (we assume it is open) private Session session; public int getRowsCount(String[] filterColumns, String[] filterValues) { // Create criteria for all entities, i.e. SELECT * FROM ... Criteria itemsCriteria = this.session.createCriteria(Item.class); // Apply data filters (if any), i.e. WHERE ... if (filterColumns != null) { // Check if filters are valid if (filterColumns.length != filterValues.length) { throw new IllegalArgumentException("Invalid filter!"); } for (int i=0; i < filterColumns.length; i++) { String column = filterColumns[i]; String value = filterValues[i]; Criterion criterion = Expression.eq(column, value); itemsCriteria.add(criterion); } } // Apply row count projection, i.e. SELECT COUNT(*) ... itemsCriteria.setProjection(Projections.rowCount()); // Return the rows count returned by the database query int recordsCount = (Integer) itemsCriteria.uniqueResult(); return recordsCount; } @SuppressWarnings("unchecked") public List<Item> getRows(int startRow, int rowsCount, String[] filterColumns, String[] filterValues, String sortColumn, boolean sortOrder) { // Create criteria for all entities, i.e. SELECT * FROM ... Criteria itemsCriteria = this.session.createCriteria(Item.class); // Apply data filters (if any), i.e. WHERE ... if (filterColumns != null) { // Check if filters are valid if (filterColumns.length != filterValues.length) { throw new IllegalArgumentException("Invalid filter!"); } for (int i=0; i < filterColumns.length; i++) { String column = filterColumns[i]; String value = filterValues[i]; Criterion criterion = Expression.eq(column, value); itemsCriteria.add(criterion); } } // Apply sorting criteria if (sortColumn != null) { Order order; if (sortOrder) { order = Order.asc(sortColumn); } else { order = Order.desc(sortColumn); } itemsCriteria.addOrder(order); } // Apply data paging itemsCriteria.setFirstResult(startRow); itemsCriteria.setMaxResults(rowsCount); // Execute query and return results List<Item> items = itemsCriteria.list(); return items; }You may need this code also:
public class ItemsTableModelServiceImpl extends HibernateServiceImpl implements TableModelService { private static final long serialVersionUID = 1L; TableColumn[] columns = { new TableColumn("Title", "Title"), new TableColumn("Description", "Description"), new TableColumn("IngestionDate", "Ingestion Date"), new TableColumn("State", "State") }; public TableColumn[] getColumns() { return columns; } public int getRowsCount(DataFilter[] filters) { ItemViewDAO itemViewDAO = new ItemViewDAO(); String[] filterColumns = ReflectionUtils.extractFilterColumns(filters); String[] filterValues = ReflectionUtils.extractFilterValues(filters); int rowsCount = itemViewDAO.getRowsCount(filterColumns, filterValues); return rowsCount; } public String[][] getRows(int startRow, int rowsCount, DataFilter[] filters, String sortColumn, boolean sortOrder) { ItemViewDAO itemViewDAO = new ItemViewDAO(); String[] filterColumns = ReflectionUtils.extractFilterColumns(filters); String[] filterValues = ReflectionUtils.extractFilterValues(filters); List<ItemView> items = itemViewDAO.getRows(startRow, rowsCount, filterColumns, filterValues, sortColumn, sortOrder); String[][] tableRows = ReflectionUtils.convertToStringArray(items, this.columns); return tableRows; } }This Hibernate session management interceptor class could also be useful:
public class HibernateServiceImpl extends RemoteServiceServlet { private static final long serialVersionUID = 1L; @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { try { HibernateSessionManager.openSession(); super.service(request, response); HibernateSessionManager.commitTransaction(); } catch (Exception ex) { HibernateSessionManager.rollbackTransaction(); if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } else { throw new ServletException(ex); } } finally { HibernateSessionManager.closeSession(); } } }I think it would be better if, instead of passing the filters into both getRowsCount and getRows, there was a single "setFilters" call, and then both getRowsCount and getRows would use those filters. In my implementation, I'd like to make a server-side copy of the filtered data just once, and then return the rows from that copy, instead of having to re-filter the data on every call.
I do not agree with ptomblin. Doing so you will have to create own instance of service for each of your user. Or otherwise, filters of concurrent users will be mixed in one server-side instance.