Announcement Announcement Module
Collapse
No announcement yet.
Roo jsf lazy loading with p:datatable Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Roo jsf lazy loading with p:datatable

    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

    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;
    It worked good and can serve to insiration for you.

    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

  • #2
    Thanks for the input

    Problem is that I have to create for all entities this lazy load class.
    Since I will be auto-generating the code, it's not such a big deal.
    LazyEntityDataModel<T extends RooJpaActiveRecord>
    I can't hardcode any Roo annotations or classes there is no Roo runtime. It also has to work with our Spring Data JPA repositories, not just Active Record methods.

    I will look into this.
    Last edited by Alan Stewart; Dec 7th, 2011, 04:23 PM.

    Comment


    • #3
      Hi,

      Thanks for reply.
      I am going to update jsf addon to generate this lazy load class for concrete entity when scaffold is called.
      All my other attempts failed and this will be best solution.
      Just not sure if there have to be second criteria query for count. (I am not so skilled in JPA).

      Another question is should I commit my changes to roo? And What happends after these commits?
      Thanks valerian.

      Comment


      • #4
        It would be easier for you to just create a small JSF project with one or two entities, push-in all the ITD code, and make the necessary modifications to use the LazyDataModel. It's then a simple matter for me to auto-generate this.

        Comment


        • #5
          Hi,

          I made this updates in addon-jsf.
          Unfortunately it's imposible for me for some reason to commit these changes to GitHub
          https://github.com/SpringSource/spring-roo/info/refs with code 403 forbidden, but most probably i have correct pgp username and password.
          Is it alowed to push changes there?
          If not where can i upload changed files?

          7 files have been modified:
          JsfCommands.java
          JsfJavaType.java
          JsfOperations.java
          JsfOperationsImpl.java
          JsfManagedBeanMetadata.java
          LazyLoadModel-template.java
          content-template.xhtml

          If you are interested to send these files via e-mail do not hesitate to just ask.

          Valerian.

          Comment


          • #6
            You can't commit directly to our source code repo. You need to submit a pull request on GitHub. Also, before we can accept the request, you also have to submit an online contributers agreement (see https://support.springsource.com/spr...mmitter_signup)

            Comment


            • #7
              You can send the files to stewarta at vmware dot com. But I can't integrate any code until you have submitted the agreement mentioned above.

              Comment


              • #8
                Hi,

                I accepted licence.
                Assumed that project is Spring Roo and leader is you, Alan Stewart.

                I am going to send you that files.
                Known bugs are that in file JsfManagedBeanMetadata.java#1112 is import on generated lazy load model class.
                builder.getImportRegistrationResolver().addImports (new JavaType(entity.getFullyQualifiedTypeName() + "LazyLoadModel"));
                which is wrong package and i dont know how to retreive right one. (It should not be entity but lazy load class package)

                Also if community is interested how did I done some job with updating existing addon for my own purposes I can share some tutorial or how to.
                I am trying to hold this informations in readme.txt. (Realy good convension )

                This is my first addon update so bear with me.

                valerian

                Comment

                Working...
                X