Hi,
Here is my implementation of lazy loading primefaces datatable.
See primefaces example http://www.primefaces.org/showcase-l...atableLazy.jsf
Here is my implementation for Account entity class.
I created public class LazyAccountDataModel extends LazyDataModel<Account> and here is load method
It worked good and can serve to insiration for you.Code:@Override public List<Account> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) { logger.debug("loading lazily accounts"); List<Account> data = new ArrayList<Account>(); EntityManager entityManager = Account.entityManager(); // Criteria CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Account> accountQuery = criteriaBuilder.createQuery(Account.class); // From Root<Account> from = accountQuery.from(Account.class); //sort if(sortField != null) { if (sortOrder == SortOrder.ASCENDING) { accountQuery.orderBy(criteriaBuilder.asc(from.get(sortField))); } else { accountQuery.orderBy(criteriaBuilder.desc(from.get(sortField))); } } // filters List<Predicate> predicates = new ArrayList<Predicate>(); for(Iterator<String> it = filters.keySet().iterator(); it.hasNext();) { String filterProperty = it.next(); // table column name = field name String filterValue = filters.get(filterProperty); Expression<String> literal = criteriaBuilder.literal((String)filterValue); predicates.add(criteriaBuilder.like(from.<String>get(filterProperty), literal)); } accountQuery.where(predicates.toArray(new Predicate[predicates.size()])); // paginate data = entityManager.createQuery(accountQuery).setFirstResult(first) .setMaxResults(getPageSize()).getResultList(); // row count CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class); countQuery.select(criteriaBuilder.count(countQuery.from(Account.class))); countQuery.where(predicates.toArray(new Predicate[predicates.size()])); int rowCount = entityManager.createQuery(countQuery).getSingleResult().intValue(); setRowCount(rowCount); return data;
Problem is that I have to create for all entities this lazy load class.
Or I can make it generic ( type T ) and by reflections getMethod obtain entityManager, find and count methods.
This methods are generated by Roo with annotation @RooJpaActiveRecord.
public class LazyEntityDataModel<T> extends LazyDataModel<T>
But it will be looks like this
@SuppressWarnings("unchecked")
@Override
public T getRowData(String rowKey) {
// Originaly it was return Account.findAccount(new Long(rowKey));
try {
Method findMethod = t.getClass().getMethod("find" + t.getClass().getName(), Long.class);
return (T) findMethod.invoke(this, new Long(rowKey));
... // catch reflections exceptions
This seems for me to be better approach, but LazyEntityDataModel<T> cannot be sure that T have methods
entityManager() , find, count ...
It's possible to LazyEntityDataModel<T extends RooJpaActiveRecord> to be sure that T have these methods and then we no need to have that mess with reflections, but all entities will have to then implement RooJpaActiveRecord.
That are yours oppinions?
Thanks valerian


Reply With Quote
)