LazyLoading+filter+sort with JPA 2.0 example

UI Components for JSF
Post Reply
luisalves00
Posts: 71
Joined: 21 Feb 2011, 18:37

13 May 2011, 18:31

Hello,

Anyone has an example of LazyLoading with filters and sort with JPA 2.0 (EclipseLink). The most important thing is the query with the filters and sort that comes from the lazyLoadingModel load method...think I have to use the Criteria API...

best regards,
la00

robert.m
Posts: 226
Joined: 07 Dec 2010, 22:52
Location: Salzburg/Austria

14 May 2011, 11:44

Please use the search function before creating a new thread, as this has been discussed before:
http://primefaces.prime.com.tr/forum/vi ... jpa#p34970

bochkov
Posts: 8
Joined: 23 Feb 2011, 08:55

16 May 2011, 06:25

Here is my code for JPA

Code: Select all

public class QueryBundle {

    Expression where;
    Root root;
    CriteriaQuery query;
    CriteriaBuilder builder;
    EntityManager em;
    List<Order> orders = new LinkedList<Order>();

    public QueryBundle(EntityManager em, Class entityClass) {
        this.em = em;
        builder = em.getCriteriaBuilder();
        query = builder.createQuery();
        root = query.from(entityClass);
    }

    public QueryBundle setSelect(String path, boolean distinct) {
        query.select(createPath(path));
        query.distinct(distinct);
        return this;
    }

    public QueryBundle setSelect(String path) {
        return setSelect(path, true);
    }

    public static QueryBundle createReadAllQuery(EntityManager em, Class entityClass) {
        QueryBundle q = new QueryBundle(em, entityClass);
        q.query.select(q.root);
        return q;
    }

    public static QueryBundle createReadCountQuery(EntityManager em, Class entityClass) {
        QueryBundle q = new QueryBundle(em, entityClass);
        q.query.select(q.builder.count(q.root));
        return q;
    }

    public CriteriaBuilder getBuilder() {
        return builder;
    }

    public CriteriaQuery getQuery() {
        return query;
    }

    public Root getRoot() {
        return root;
    }

    public Expression getWhere() {
        return where;
    }

    public Query compile() {
        if (where != null) {
            query.where(where);
        }
        if (!orders.isEmpty()) {
            query.orderBy(orders);
        }
        return em.createQuery(query);
    }

    public QueryBundle setFilter(Map filter) {
        if (filter != null) {
            for (Object key : filter.keySet()) {
                appendFilter(String.valueOf(key), filter.get(key));
            }
        }
        return this;
    }

    public QueryBundle appendOrder(String path, boolean desc) {
        if (path == null) {
            return this;
        }
        return appendOrder(createPath(path), desc);
    }

    public QueryBundle appendOrder(Path path, boolean desc) {
        Order order = desc ? builder.desc(path) : builder.asc(path);
        if (!orders.contains(order)) {
            orders.add(order);
        }
        return this;
    }

    public QueryBundle appendFilter(String property, Object expr) {
        if (expr instanceof String) {
            return appendLikeFilter(property, (String) expr);
        } else {
            return appendEqFilter(property, expr);
        }
    }

    public QueryBundle appendEqFilter(String property, Object expr) {
        return appendEqFilter(property, true, true, expr);
    }

    public QueryBundle appendEqFilter(String property, boolean include, Object expr) {
        return appendEqFilter(property, include, true, expr);
    }

    public QueryBundle appendEqFilter(String property, boolean include, boolean and, Object expr) {
        Path path = createPath(property);
        Expression e = createInPredicate(expr, path);
        if (!include) {
            e = builder.not(e);
        }
        if (where != null) {
            if (and) {
                where = builder.and(where, e);
            } else {
                where = builder.or(where, e);
            }
        } else {
            where = e;
        }
        return this;
    }

    public QueryBundle appendLikeFilter(String property, String expr) {
        return appendLikeFilter(property, true, true, expr);
    }

    public QueryBundle appendLikeFilter(String property, boolean include, String expr) {
        return appendLikeFilter(property, include, true, expr);
    }

    public QueryBundle appendLikeFilter(String property, boolean include, boolean and, String expr) {
        Path path = createPath(property);
        Expression e = builder.like(path, expr);
        if (!include) {
            e = builder.not(e);
        }
        if (where != null) {
            if (and) {
                where = builder.and(where, e);
            } else {
                where = builder.or(where, e);
            }
        } else {
            where = e;
        }
        return this;
    }

    Path createPath(String path) {
        Path result = root;
        for (String sub : path.split("\\.")) {
            result = result.get(sub);
        }
        return result;
    }

    public static Predicate createInPredicate(Object value, Path path) {
        if (value instanceof Collection) {
            return path.in((Collection) value);
        } else if (value instanceof Object[]) {
            return path.in((Object[]) value);
        } else {
            return path.in(value);
        }
    }
}
i don't show Facade.java, is interface for local or remote using

Code: Select all

public abstract class AbstractFacade<T> implements Facade<T> {

    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    @Override
    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    @Override
    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    @Override
    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    @Override
    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    protected QueryBundle createQueryBundle(){
        return new QueryBundle(getEntityManager(), entityClass);
    }
    protected QueryBundle createReadAllQueryBundle() {
        return QueryBundle.createReadAllQuery(getEntityManager(), entityClass);
    }

    protected Query createReadAllQuery() {
        return createReadAllQueryBundle().compile();
    }

    protected QueryBundle createReadCountQueryBundle() {
        return QueryBundle.createReadCountQuery(getEntityManager(), entityClass);
    }

    protected Query createReadCountQuery() {
        return createReadCountQueryBundle().compile();
    }

    @Override
    public List<T> findAll() {

        return createReadAllQueryBundle().compile().getResultList();
    }

    @Override
    public List<T> findRange(int[] range) {
        Query q = createReadAllQuery();
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    @Override
    public int count() {
        return ((Long) createReadCountQuery().getSingleResult()).intValue();
    }

    @Override
    public List<T> load(int start, int length, String order, boolean desc, Map<String, String> map) {
        QueryBundle qb = createReadAllQueryBundle().appendOrder(order, desc).setFilter(map);
        javax.persistence.Query q = qb.compile().setMaxResults(length).setFirstResult(start);
        return q.getResultList();
    }
}

Code: Select all

public abstract class PrimeJpaBean<T> {

    T current;
    LazyDataModel<T> dataModel;
    int selectedIndex;

    public LazyDataModel<T> getDataModel() {
        return dataModel;
    }

    @PostConstruct
    void createDataModel() {
        LazyDataModel m = new LazyDataModel<T>() {

            @Override
            public List<T> load(int start, int size, String order, boolean desc, Map<String, String> filter) {
                return getFacade().load(start, size, order, desc, filter);
            }
        };
        m.setRowCount(getFacade().count());
        dataModel = m;

    }

    public abstract Facade<T> getFacade();

    public T getCurrent() {
        return current;
    }

    public void setCurrent(T current) {
        this.current = current;
    }

    public String prepareEdit() {
        current = (T) getDataModel().getRowData();
        selectedIndex = getDataModel().getRowIndex();
        return "Edit";
    }

    public String edit() {
        if (current != null) {
            try {
                getFacade().edit(current);
            } catch (Exception e) {
                JsfUtil.addErrorMessage(e, "error");
            }
            JsfUtil.addSuccessMessage("the object'" + current + "' updated");
        } else {
            JsfUtil.addErrorMessage("Object is empty");
        }
        return "Edit";
    }

    public String prepareDelete() {
        current = (T) getDataModel().getRowData();
        selectedIndex = getDataModel().getRowIndex();
        return "List";
    }

    public String delete() {
        if (current != null) {
            try {
                //getFacade().remove(current);
            } catch (Exception e) {
                JsfUtil.addErrorMessage(e, " delete error");
            }
            JsfUtil.addSuccessMessage("object deleted");
        } else {
            JsfUtil.addErrorMessage("object is empty");
        }
        createDataModel();
        return "List";
    }
}
for using this, you must implement abstract methods
in facde is "getEntityManager()" and in PrimeJpaBean is "getFacade()"

Code: Select all

@ManagedBean
@SessionScoped
public class MyEntityBean extends PrimeJpaBean<MyEntity> {

    @EJB
    MyEntityFacadeLocal facade;

    @Override
    public Facade<MyEntity> getFacade() {
        return facade;
    }
}

Code: Select all


@Stateless
public class MyEntityFacade extends AbstractFacade<MyEntity> implements MyEntityFacadeLocal, MyEntityFacadeRemote {

    @PersistenceContext(unitName = "myentityPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public MyEntityFacade() {
        super(MyEntity.class);
    }
}

this code I wrote recently and has not had time to test well,
but I think that the idea is clear
Glassfish 3.1, Mojarra 2.1.3

anatolse
Posts: 19
Joined: 14 Apr 2011, 11:09
Location: Russia, Moscow
Contact:

17 May 2011, 15:29


luisalves00
Posts: 71
Joined: 21 Feb 2011, 18:37

26 May 2011, 12:24

tks for you suggestions...

the main issue is joining tables. Trying to follow the last example

luisalves00
Posts: 71
Joined: 21 Feb 2011, 18:37

26 May 2011, 19:00

Got realy strange behaviour of the paginator....

Used this pattern

Code: Select all

  public LazyDataModel getCardItemsLazy() {
        if (cartaoItemsLazy == null) {
            cartaoItemsLazy = new LazyDataModel() {

                @Override
                public List load(int first, int pageSize, String sortField, boolean sortOrder, Map filters) {
                    LazyDataModelContainer<Card> l = getCardJpaController().findCardEntitiesLazy(first, pageSize, sortField, sortOrder, filters);
                    this.setRowCount(l.getRowCount());  //LazyDataModelContainer contains the count and the list of results...with a break point I see the correct count value
                    return l.getResultList();
                }
            };
            int totalRowCount = getCardJpaController().getCardCount();  //If I don't do this...the first time I don't get any result....
            cartaoItemsLazy.setRowCount(totalRowCount);
        }
        return cartaoItemsLazy;  //DO I NEED TO RESET SOMETHING?
    }
*//DO I NEED TO RESET SOMETHING?

[SOLUTION]

build PF from source (used revision 4342)

and added this fix http://code.google.com/p/primefaces/iss ... %20Summary

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 55 guests