import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.el.Expression; import javax.faces.context.FacesContext; import org.ajax4jsf.model.DataVisitor; import org.ajax4jsf.model.Range; import org.ajax4jsf.model.SequenceRange; import org.ajax4jsf.model.SerializableDataModel; import org.richfaces.model.ExtendedFilterField; import org.richfaces.model.FilterField; import org.richfaces.model.Modifiable; import org.richfaces.model.Ordering; import org.richfaces.model.SortField2; public abstract class PaginatingDataModel<T, U> extends SerializableDataModel implements Modifiable { private static final long serialVersionUID = 2954923950179861809L; protected U currentPk; protected int rowIndex; protected boolean descending = true; protected String sortField = null; protected HashMap<String,Object> filterMap = new HashMap<String,Object>(); protected boolean detached = false; protected List<U> wrappedKeys = new ArrayList<U>(); protected Integer rowCount; protected Map<U, T> wrappedData = new HashMap<U, T>(); /** * * @see org.ajax4jsf.model.ExtendedDataModel#getRowKey() */ @Override public Object getRowKey() { return currentPk; } /** * * @see org.ajax4jsf.model.ExtendedDataModel#setRowKey(java.lang.Object) */ @SuppressWarnings("unchecked") @Override public void setRowKey(final Object key) { this.currentPk = (U) key; } /** * * @see org.ajax4jsf.model.SerializableDataModel#update() */ @Override public void update() { detached = false; } /** * * @see org.ajax4jsf.model.ExtendedDataModel#getSerializableModel(org.ajax4jsf.model.Range) */ @Override public SerializableDataModel getSerializableModel(final Range range) { if (wrappedKeys != null) { detached = true; return this; } return null; } /** * * @see javax.faces.model.DataModel#setRowIndex(int) */ @Override public void setRowIndex(final int arg0) { rowIndex = arg0; } /** * * @see javax.faces.model.DataModel#setWrappedData(java.lang.Object) */ @Override public void setWrappedData(final Object data) { throw new UnsupportedOperationException(); } /** * * @see javax.faces.model.DataModel#getRowIndex() */ @Override public int getRowIndex() { return rowIndex; } /** * * @see javax.faces.model.DataModel#getWrappedData() */ @Override public Object getWrappedData() { throw new UnsupportedOperationException(); } /** * * @see org.ajax4jsf.model.ExtendedDataModel#walk(javax.faces.context.FacesContext, org.ajax4jsf.model.DataVisitor, * org.ajax4jsf.model.Range, java.lang.Object) */ @Override public void walk(final FacesContext context, final DataVisitor visitor, final Range range, final Object argument) throws IOException { final int firstRow = ((SequenceRange) range).getFirstRow(); final int numberOfRows = ((SequenceRange) range).getRows(); if (detached) { for (final U key : wrappedKeys) { setRowKey(key); visitor.process(context, key, argument); } } else { // if not serialized, than we request data from data provider wrappedKeys = new ArrayList<U>(); for (final T object : findObjects(firstRow, numberOfRows, sortField, filterMap, descending)) { wrappedKeys.add(getId(object)); wrappedData.put(getId(object), object); visitor.process(context, getId(object), argument); } } } /** * * @see javax.faces.model.DataModel#isRowAvailable() */ @Override public boolean isRowAvailable() { if (currentPk == null) { return false; } if (wrappedKeys.contains(currentPk)) { return true; } if (wrappedData.entrySet().contains(currentPk)) { return true; } try { if (getObjectById(currentPk) != null) { return true; } } catch (final Exception e) { } return false; } /** * * @see javax.faces.model.DataModel#getRowData() */ @Override public Object getRowData() { if (currentPk == null) { return null; } T object = wrappedData.get(currentPk); if (object == null) { object = getObjectById(currentPk); wrappedData.put(currentPk, object); } return object; } /** * * @see javax.faces.model.DataModel#getRowCount() */ @Override public int getRowCount() { if (rowCount == null) { rowCount = getNumRecords(filterMap).intValue(); } return rowCount; } @Override public void modify(List<FilterField> filterFields, List<SortField2> sortFields) { filterMap.clear(); SortField2 sortField2 = null; String expressionStr = null; ExtendedFilterField extendedFilterField = null; Expression expression = null; String value = null; if (sortFields != null && !sortFields.isEmpty()) { sortField2 = sortFields.get(0); expression = sortField2.getExpression(); expressionStr = expression.getExpressionString(); if (!expression.isLiteralText()) { expressionStr = expressionStr.replaceAll("[#|$]{1}\\{.*?\\.", "").replaceAll("\\}", ""); } this.sortField = expressionStr; if (sortField2.getOrdering() == Ordering.DESCENDING) { this.descending = true; } else { this.descending = false; } } if (filterFields != null && !filterFields.isEmpty()) { for (FilterField filterField : filterFields) { if (filterField instanceof ExtendedFilterField) { extendedFilterField = (ExtendedFilterField) filterField; value = extendedFilterField.getFilterValue(); if (value != null && !value.equals("")) { expression = extendedFilterField.getExpression(); expressionStr = expression.getExpressionString(); if (!expression.isLiteralText()) { expressionStr = expressionStr.replaceAll("[#|$]{1}\\{.*?\\.", "").replaceAll("\\}", ""); } filterMap.put(expressionStr, value); } } } } } /** * @param object * * @return U */ public abstract U getId(T object); /** * * @param firstRow * * @param numberOfRows * * @param sortField * * @param descending * * @return List<T> */ public abstract List<T> findObjects(int firstRow, int numberOfRows, String sortField, HashMap<String,Object> filterMap, boolean descending); /** * * @param id * * @return T */ public abstract T getObjectById(U id); /** * * @return Long */ public abstract Long getNumRecords(HashMap<String,Object> filterMap); }
PersonPaginatingDataModel.java
import java.util.HashMap; import java.util.List; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import at.ooegkk.svnet.juhealth.entity.Person; import at.ooegkk.svnet.juhealth.service.PersonService; @Name("personPaginatingDataModel") public class PersonPaginatingDataModel extends PaginatingDataModel<Person, Long> { private static final long serialVersionUID = 1868068053701471139L; @In(required = false) private PersonService personService; /** * @see PaginatingDataModel#getId */ @Override public Long getId(Person person) { return person.getId(); } /** * @see PaginatingDataModel#findObjects */ @Override public List<Person> findObjects(int firstRow, int maxResult, String sortField, HashMap<String,Object> filterMap, boolean descending) { return personService.getRange(firstRow, maxResult, sortField, filterMap, descending); } /** * @see PaginatingDataModel#getObjectById(java.lang.Object) */ @Override public Person getObjectById(Long id) { return personService.getPersonById(id); } /** * * @see PaginatingDataModel#getNumRecords */ @Override public Long getNumRecords(HashMap<String,Object> filterMap) { return personService.getCount(filterMap); } }
PersonService.java
import java.util.HashMap; import java.util.List; import javax.ejb.Remote; import at.ooegkk.svnet.juhealth.entity.Person; @Remote public interface PersonService { public List<Person> findAllPersons(); public void save(Person p); public void merge(Person p); public void remove(Person p); public Person getPersonById(Long id); public Long getCount(HashMap<String,Object> filterMap); public List<Person> getRange(Integer firstRow, Integer maxResult, String sortField, HashMap<String,Object> filterMap, boolean descending); }
PersonServiceImpl.java
import java.util.HashMap; import java.util.List; import javax.ejb.EJB; import javax.ejb.Stateless; import at.ooegkk.svnet.juhealth.dao.GenericDAO; import at.ooegkk.svnet.juhealth.dao.PersonDAO; import at.ooegkk.svnet.juhealth.entity.Person; import at.ooegkk.svnet.juhealth.service.PersonService; @Stateless @SuppressWarnings("unchecked") public class PersonServiceImpl implements PersonService { @EJB(name="svnet-juhealth-EAR/PersonDAOImpl/local") private PersonDAO personDAOImpl; public List<Person> findAllPersons() { List<Person> allPersons = personDAOImpl.findAll(Person.class); return allPersons; } public void save(Person person) { personDAOImpl.persist(person); } public void merge(Person person) { personDAOImpl.merge(person); } public void remove(Person person) { personDAOImpl.remove(person); } public Person getPersonById(Long id) { Person p = (Person) personDAOImpl.findById(Person.class, id); return p; } public Long getCount(HashMap<String,Object> filterMap) { Long count = personDAOImpl.getCount(Person.class, filterMap); return count; } public List<Person> getRange(Integer firstRow, Integer maxResult, String sortField, HashMap<String,Object> filterMap, boolean descending) { List<Person> list = null; if (descending) { list = personDAOImpl.findByFilter(Person.class, firstRow, maxResult, sortField, GenericDAO.SORT_ORDER.DESC, filterMap); } else { list = personDAOImpl.findByFilter(Person.class, firstRow, maxResult, sortField, GenericDAO.SORT_ORDER.ASC, filterMap); } return list; } }
GenericDAO.java
package at.ooegkk.svnet.juhealth.dao; import java.util.HashMap; import java.util.List; import java.util.Set; import javax.ejb.Local; @SuppressWarnings("unchecked") @Local public interface GenericDAO { public enum SORT_ORDER { ASC, DESC }; public Object findById(Class entityClass, long id); public List findAll(Class entityClass); public List findAll(Class entityClass, String orderByAttribute, SORT_ORDER sortOrder); public List findAll(Class entityClass, int maxResult); public List findAll(Class entityClass, int firstRow, int maxResult); public List findAll(Class entityClass, int maxResult, String orderByAttribute, SORT_ORDER sortOrder); public void persist(Object entity, boolean flushImmediate); public void persist(Object entity); public Object merge(Object entity, boolean flushImmediate); public Object merge(Object entity); public void remove(Object entity, boolean flushImmediate); public void remove(Object entity); public Set<String> exludeNames(); public Long getCount(Class entityClass); public Long getCount(Class entityClass, HashMap<String,Object> filterMap); public List findByFilter(Class entityClass, int firstRow, int maxResult, String orderByAttribute, SORT_ORDER sortOrder, HashMap<String, Object> filterMap); }
GenericDAOImpl.java
import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import at.ooegkk.svnet.juhealth.dao.GenericDAO; @SuppressWarnings("unchecked") @Stateless public class GenericDAOImpl implements GenericDAO { @PersistenceContext(unitName="svnet-juhealth") private EntityManager entityManager; public EntityManager getEntityManager() { return entityManager; } public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } public Object findById(Class entityClass, long id) { return getEntityManager().find(entityClass, id); } public List findAll(Class entityClass) { return getEntityManager().createQuery( "select e from " + entityClass.getName() + " e ") .getResultList(); } public List findAll(Class entityClass, String orderByAttribute, SORT_ORDER sortOrder) { String sortOrderString = "desc"; if (sortOrder == SORT_ORDER.ASC) { sortOrderString = "asc"; } return getEntityManager().createQuery( "select e from " + entityClass.getName() + " e order by " + orderByAttribute + " " + sortOrderString).getResultList(); } public List findAll(Class entityClass, int maxResult) { Query q = getEntityManager().createQuery( "select e from " + entityClass.getName() + " e "); if (maxResult > 0) { q.setMaxResults(maxResult); } return q.getResultList(); } public List findAll(Class entityClass, int firstRow, int maxResult) { Query q = getEntityManager().createQuery( "select e from " + entityClass.getName() + " e "); if (firstRow > 0) { q.setFirstResult(firstRow); } if (maxResult > 0) { q.setMaxResults(maxResult); } return q.getResultList(); } public List findAll(Class entityClass, int maxResult, String orderByAttribute, SORT_ORDER sortOrder) { String sortOrderString = "desc"; if (sortOrder == SORT_ORDER.ASC) { sortOrderString = "asc"; } Query q = getEntityManager().createQuery( "select e from " + entityClass.getName() + " e order by " + orderByAttribute + " " + sortOrderString); if (maxResult > 0) { q.setMaxResults(maxResult); } return q.getResultList(); } public void persist(Object entity, boolean flushImmediate) { getEntityManager().persist(entity); if (flushImmediate) getEntityManager().flush(); } public void persist(Object entity) { this.persist(entity, false); } public Object merge(Object entity, boolean flushImmediate) { Object obj = getEntityManager().merge(entity); if (flushImmediate) getEntityManager().flush(); return obj; } public Object merge(Object entity) { return this.merge(entity, false); } public void remove(Object entity, boolean flushImmediate) { getEntityManager().remove(getEntityManager().merge(entity)); if (flushImmediate) getEntityManager().flush(); } public void remove(Object entity) { this.remove(entity, false); } public Set<String> exludeNames() { return new HashSet<String>(); } public Long getCount(Class entityClass) { Query q = getEntityManager().createQuery( "select count(e) from " + entityClass.getName() + " e "); return (Long) q.getSingleResult(); } public Long getCount(Class entityClass, HashMap<String,Object> filterMap) { StringBuffer query = new StringBuffer(); query.append("select count(e) from " + entityClass.getName() + " e"); // where clause query.append(this.getWhereClause(filterMap)); Query q = getEntityManager().createQuery(query.toString()); // parameter q = this.getParameteredQuery(q, filterMap); return (Long) q.getSingleResult(); } public List findByFilter(Class entityClass, int firstRow, int maxResult, String orderByAttribute, SORT_ORDER sortOrder, HashMap<String,Object> filterMap) { StringBuffer query = new StringBuffer(); query.append("SELECT e FROM " + entityClass.getName() + " e"); // sort order String sortOrderString = "desc"; if (sortOrder == SORT_ORDER.ASC) { sortOrderString = "asc"; } // where clause query.append(this.getWhereClause(filterMap)); // order by if (orderByAttribute != null) { query.append(" ORDER BY " + orderByAttribute + " " + sortOrderString); } Query q = getEntityManager().createQuery(query.toString()); // parameter q = this.getParameteredQuery(q, filterMap); if (firstRow > 0) { q.setFirstResult(firstRow); } if (maxResult > 0) { q.setMaxResults(maxResult); } return q.getResultList(); } private String getWhereClause(HashMap<String,Object> filterMap) { StringBuffer query = new StringBuffer(); if (filterMap != null && !filterMap.isEmpty()) { query.append(" WHERE"); boolean first = true; for (String column : filterMap.keySet()) { if (first) { first = false; } else { query.append(" AND"); } if (filterMap.get(column) instanceof String) { query.append(" UPPER(e." + column + ") LIKE :" + column); } else { query.append(" e." + column + " = :" + column); } } } return query.toString(); } private Query getParameteredQuery(Query q, HashMap<String,Object> filterMap) { if (filterMap != null && !filterMap.isEmpty()) { for (String column : filterMap.keySet()) { if (filterMap.get(column) instanceof String) { String value = (String) filterMap.get(column); q.setParameter(column, value.toUpperCase() + "%"); } else { q.setParameter(column, filterMap.get(column)); } } } return q; } }
PersonDAO.java
import javax.ejb.Local; @Local public interface PersonDAO extends GenericDAO { }
PersonDAOImpl.java
import javax.ejb.Stateless; import at.ooegkk.svnet.juhealth.dao.PersonDAO; @Stateless public class PersonDAOImpl extends GenericDAOImpl implements PersonDAO { }
AbstractEntity.java
import java.io.Serializable; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.MappedSuperclass; @MappedSuperclass public class AbstractEntity implements Serializable { /** * */ private static final long serialVersionUID = 1L; private Long id; @Id @GeneratedValue(strategy=GenerationType.AUTO) public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
Person.java
import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.OneToOne; import javax.persistence.Table; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; import org.hibernate.validator.Length; import org.hibernate.validator.NotNull; import org.jboss.seam.annotations.Name; import at.ooegkk.intranet.example.validator.VSNR; @Name("person") @Entity @Table @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) public class Person extends AbstractEntity implements Serializable { /** * */ private static final long serialVersionUID = 1L; private String vorname; private String nachname; private String vsnr; private Date geburtsdatum; private Address adresse = new Address(); @Column @NotNull(message="#{messages['field.required']}") public String getVorname() { return vorname; } public void setVorname(String vorname) { this.vorname = vorname; } @Column public String getNachname() { return nachname; } public void setNachname(String nachname) { this.nachname = nachname; } @Column @NotNull @Length(max=10,min=10) public String getVsnr() { return vsnr; } public void setVsnr(String vsnr) { this.vsnr = vsnr; } @OneToOne(targetEntity=Address.class) @Cascade(value=CascadeType.ALL) public Address getAdresse() { return adresse; } public void setAdresse(Address adresse) { this.adresse = adresse; } @Column public Date getGeburtsdatum() { return geburtsdatum; } public void setGeburtsdatum(Date geburtsdatum) { this.geburtsdatum = geburtsdatum; } }
Address.java
import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; import org.hibernate.validator.NotNull; import org.jboss.seam.annotations.Name; @Entity @Table @Name("adresse") public class Address extends AbstractEntity implements Serializable { /** * */ private static final long serialVersionUID = 1L; private Integer plz; private String ort; private String strasse; @Column public Integer getPlz() { return plz; } public void setPlz(Integer plz) { this.plz = plz; } @Column public String getOrt() { return ort; } public void setOrt(String ort) { this.ort = ort; } @Column @NotNull public String getStrasse() { return strasse; } public void setStrasse(String strasse) { this.strasse = strasse; } }
index.xhtml
<rich:dataTable value="#{personPaginatingDataModel}" var="person" rows="3" reRender="scroller" id="simpletable" width="100%" rowClasses="firstrow,secondrow"< <f:facet name="header"< <h:outputText value="Personen"/< </f:facet< <rich:column width="10%"< <s:link action="#{personManager.personEdit}"< <f:param name="personId" value="#{person.id}"/< <img src="/img/icon_bearbeiten.gif" alt="Bearbeiten"/< </s:link< </rich:column< <rich:column width="18%"< <f:facet name="header"< <h:outputText value="SVNR"/< </f:facet< <h:outputText value="#{person.vsnr}"/< </rich:column< <rich:column sortBy="#{person.vorname}" filterBy="#{person.vorname}" filterEvent="onkeyup" filterValue="#{personManager.currentVornameFilterValue}" width="18%"< <f:facet name="header"< <h:outputText value="Vorname"/< </f:facet< <h:outputText value="#{person.vorname}"/< </rich:column< <rich:column filterBy="#{person.nachname}" filterEvent="onkeyup" filterValue="#{personManager.currentNachnameFilterValue}" width="18%"< <f:facet name="header"< <h:outputText value="Nachname"/< </f:facet< <h:outputText value="#{person.nachname}"/< </rich:column< <rich:column width="18%"< <f:facet name="header"< <h:outputText value="Strasse"/< </f:facet< <h:outputText value="#{person.adresse.strasse}"/< </rich:column< <rich:column width="8%"< <f:facet name="header"< <h:outputText value="PLZ"/< </f:facet< <h:outputText value="#{person.adresse.plz}"/< </rich:column< <rich:column width="10%"< <f:facet name="header"< <h:outputText value="Ort"/< </f:facet< <h:outputText value="#{person.adresse.ort}"/< </rich:column< </rich:dataTable< <rich:datascroller id="scroller" renderIfSinglePage="false" for="simpletable"<</rich:datascroller<
Edit at 2012/09/26: The reason that some readers were asking for the source code of the PersonManager, I edited this post. Because I have improved the PersonManager since the creation of the first post, I inserted an older version from the repository. Hopefully it is compatible with the other code.
PersonManager
import java.util.List; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Begin; import org.jboss.seam.annotations.End; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.web.RequestParameter; import at.ooegkk.svnet.juhealth.datamodel.PersonPaginatingDataModel; import at.ooegkk.svnet.juhealth.entity.Person; import at.ooegkk.svnet.juhealth.service.PersonService; @Name("personManager") @Scope(ScopeType.SESSION) public class PersonManager { @In(required = false) private PersonService personService; @In(create = true) @Out(required = false) public Person person; @Out(required = false) public Person searchPerson = new Person(); @RequestParameter public Long personId; public String currentVornameFilterValue; public String currentNachnameFilterValue; @In(create = true) public PersonPaginatingDataModel personPaginatingDataModel; public PersonManager() { } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public Person getSearchPerson() { return searchPerson; } public void setSearchPerson(Person searchPerson) { this.searchPerson = searchPerson; } public PersonPaginatingDataModel getPersonPaginatingDataModel() { return personPaginatingDataModel; } public void setPersonPaginatingDataModel(PersonPaginatingDataModel personPaginatingDataModel) { this.personPaginatingDataModel = personPaginatingDataModel; } public String personenList() { return "personenList"; } public String personAdd() { return "personAdd"; } @Begin(join = true) @End public String personSave() throws Exception { try { if (person.getId() == null) { this.personService.save(person); } else { this.personService.merge(person); } return "personSave"; } catch (Exception e) { throw e; } } public String personReset() throws Exception { try { person = new Person(); return "personReset"; } catch (Exception e) { throw e; } } public String personEdit() throws Exception { try { person = this.personService.getPersonById(personId); return "personEdit"; } catch (Exception e) { throw e; } } public String personenSearch() throws Exception { try { return "personenSearch"; } catch (Exception e) { throw e; } } public ListgetPersonen() throws Exception { try { return this.personService.findAllPersons(); } catch (Exception e) { throw e; } } public String getCurrentVornameFilterValue() { return currentVornameFilterValue; } public void setCurrentVornameFilterValue(String currentVornameFilterValue) { this.currentVornameFilterValue = currentVornameFilterValue; } public String getCurrentNachnameFilterValue() { return currentNachnameFilterValue; } public void setCurrentNachnameFilterValue(String currentNachnameFilterValue) { this.currentNachnameFilterValue = currentNachnameFilterValue; } }
Excellent post. Well done. I've been battling with the filtering/sorting unitl I stumbled across this. Cheers, John.
ReplyDeleteAwesome! This is the first solution that I come across in the net and actually works out of the box. Great job Alex!!!
ReplyDeleteThe only thing that is missing though is an ajaxSingle="false" inside the datascroller.
ReplyDeleteThis is because by default the performs a client-side paging so ajaxSingle=true.
In order to get the updated values in the backing bean you need the ajaxSingle="false".
Hi,
ReplyDeleteGreat post. It works very well. i have a question. I need to show the number of filtered row dynamically on the page but the RowCount gives me always the toral(initial) rowNumber. It seems that the filter values become empty when i call tha RowCount.
Could you please help me with this problem.
Thanks in advance
This saved my day. I gave some treatment to couple this on my Model and Service tiers. Works great!
ReplyDeleteThank you very much for sharing!
Hey, thanks for yor example. Can you provide the source of the personManager as well?
ReplyDeleteHi guys,
ReplyDeletesorry for the late reply but I was not very active at my blog in the last time ;)
First of all thank you for your posts.
@sole: I had the same problem and I have not found a good solution yet. My work-around was that I have a button elsewhere which opens a modal panel that shows the actual row count. If you find a better solution, please let me know!
@tardy: I will edit the post in the next time, so you can find some code of the personManager as well.
Is there a chance you could post PersonManager just to understand what "filterValue" does in general?
ReplyDeletethx in adv.
Now I have updated the post and it also shows the PersonManager. Hopefully it is compatible with the other code, because I have already improved the shown example. So I took an older version from the repository.
ReplyDeleteYou can find more information about the filterValue on the demo page of RichFaces:
http://livedemo.exadel.com/richfaces-demo/richfaces/filteringFeature.jsf?c=filtering&tab=usage
If you have more questions, please let me know!
Hi,
ReplyDeleteI have to implement dynamic pagination in my project and I have a huge data set.I want to use EhCache to store the data I have already obtained from the DB. can you please suggest at what point can I cache the data and retrieve.
Please help!!!
Hi,
ReplyDeleteI also use the dynamic pagination in a project with a huge data set. Because it only retrievs about 15 rows at one time, the caching is not necessary there. My experience is that the most users only need the first 50 rows. Additionally I provide them some fields to minimise the result set. This fields are indexed in the database and so it is possible to reach good performance as well.
So my first advice is to check if it is really necessary in your case.
If you like to use the caching mechanism, I would suggest caching in the "Data Access" Layer. When you use a ORM-tool like JPA then I would use the caching opportunities from this tool.
So it should be possible to use the dynamic pagination like presented in the blog post and add the caching in the function when the data set is retrieved from the database.
Wow... Good good excelent job! Thank you for the solution!
ReplyDeleteExcellent code, worked out fine with the textbox filters. How can i make it work with
ReplyDeleteselectbox/combobox as one of the column filter? Basically i want to filter results based on the value selected in the selectbox/combobox?
@ashokchittela
ReplyDeleteIs it possible for you to use Richfaces 4? If yes, then look at the richfaces demo showcase site, there is an example with Arrangeable model and Filtering. At the Filterin page you can find an example with a selectbox.
By the way I am working on the Richfaces 4 upgrade at the moment. So I will post the new code in the next few days...
Hi Alex, Where can I found the richfaces 4 example please?
ReplyDelete