Author: fdesbois Date: 2010-12-29 18:31:40 +0100 (Wed, 29 Dec 2010) New Revision: 448 Url: http://nuiton.org/repositories/revision/sandbox/448 Log: - remove query() method in Wrapper, better to compute one time on execution - add firstResult method Modified: jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/persistence/BaseDAOImpl.java jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/query/EntityQueryWrapper.java jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/query/QueryWrapper.java Modified: jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/persistence/BaseDAOImpl.java =================================================================== --- jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/persistence/BaseDAOImpl.java 2010-12-29 16:32:38 UTC (rev 447) +++ jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/persistence/BaseDAOImpl.java 2010-12-29 17:31:40 UTC (rev 448) @@ -1,8 +1,9 @@ package org.nuiton.sandbox.jsr317.jpa2.persistence; import javax.persistence.EntityManager; +import javax.persistence.NoResultException; +import javax.persistence.NonUniqueResultException; import javax.persistence.PersistenceContext; -import javax.persistence.TypedQuery; import java.util.List; import org.apache.commons.logging.Log; @@ -105,6 +106,9 @@ this.saveStrategy = saveStrategy; } + /** + * {@inheritDoc} + */ @SuppressWarnings({"unchecked"}) @Override public C newInstance() { @@ -217,48 +221,18 @@ return results; } - protected List<C> readAllByProperty(String property, Object value) { - - EntityQueryWrapper<C, E> query = newQueryWrapper(); - - query.addEqual(property, value); - - List<C> results = query.listResult(); - - return results; - } - - @SuppressWarnings({"unchecked"}) - protected List<C> readAllByQuery(TypedQuery<E> query) { - List<E> results = query.getResultList(); - return (List<C>) results; - } - /** * {@inheritDoc} */ @Override public int count() { CountQueryWrapper<E> query = newCountQueryWrapper(); - return query.count(); } /** - * Read first resulting entity from an input {@code query}. - * - * @param query Input query - * @return the resulting first entity + * {@inheritDoc} */ - protected static <T> T readFirst(TypedQuery<T> query) { - List<T> resultList = query.getResultList(); - if (!resultList.isEmpty()) { - return resultList.get(0); - } else { - return null; - } - } - @Override public void deleteAll() { List<C> elements = readAll(); @@ -267,6 +241,26 @@ } } + public C readByProperty(String property, Object value) throws NoResultException, NonUniqueResultException { + + EntityQueryWrapper<C, E> query = newQueryWrapper(); + + query.addEqualPredicate(property, value); + + C result = query.singleResult(); + return result; + } + + public List<C> readAllByProperty(String property, Object value) { + + EntityQueryWrapper<C, E> query = newQueryWrapper(); + + query.addEqualPredicate(property, value); + + List<C> results = query.listResult(); + return results; + } + public EntityQueryWrapper<C, E> newQueryWrapper() { return new EntityQueryWrapper<C, E>(entityManager, entityClass); } Modified: jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/query/EntityQueryWrapper.java =================================================================== --- jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/query/EntityQueryWrapper.java 2010-12-29 16:32:38 UTC (rev 447) +++ jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/query/EntityQueryWrapper.java 2010-12-29 17:31:40 UTC (rev 448) @@ -15,6 +15,7 @@ import org.apache.commons.logging.LogFactory; import org.nuiton.sandbox.jsr317.jpa2.entity.BaseEntity; import org.nuiton.sandbox.jsr317.jpa2.entity.BaseEntityImpl; +import org.springframework.util.CollectionUtils; /** * EntityQueryWrapper is an extension of QueryWrapper using the entityClass as resultClass. This wrapper also provide @@ -47,7 +48,6 @@ private static final Log logger = LogFactory.getLog(EntityQueryWrapper.class); - // TODO-fdesbois-2010-12-29 : test if it's possible to have interfaceClass as resultClass, avoiding cast in listResult and singleResult public EntityQueryWrapper(EntityManager entityManager, Class<E> entityClass) { super(entityManager, entityClass, entityClass); } @@ -116,10 +116,9 @@ * @return a List of results with entity interface type. * @see TypedQuery#getResultList() */ - @SuppressWarnings({"unchecked"}) public List<C> listResult() { - List<E> results = query().getResultList(); - return (List<C>) results; + TypedQuery<E> query = computeCriteria(); + return listResult(query); } /** @@ -132,19 +131,27 @@ */ public List<C> listResult(Integer startIndex, Integer endIndex) { + TypedQuery<E> query = computeCriteria(); + int start = 0; if (startIndex != null) { start = startIndex; - query().setFirstResult(start); + query.setFirstResult(start); } - if (endIndex != null) { - query().setMaxResults(endIndex - start + 1); + query.setMaxResults(endIndex - start + 1); } - return listResult(); + return listResult(query); } + @SuppressWarnings({"unchecked"}) + protected List<C> listResult(TypedQuery<E> query) { + List<E> results = query.getResultList(); + // Safe cast because E implements C (BaseEntityImpl implements BaseEntity) + return (List<C>) results; + } + /** * Return a single result from the current query. * @@ -155,8 +162,27 @@ */ @SuppressWarnings({"unchecked"}) public C singleResult() throws NonUniqueResultException, NoResultException { - E result = query().getSingleResult(); + TypedQuery<E> query = computeCriteria(); + E result = query.getSingleResult(); + // Safe cast because E implements C (BaseEntityImpl implements BaseEntity) return (C) result; } + /** + * Return the first result from the current query. If you don't want exceptions we {@link #singleResult()} you can + * use this method that retrieve the first row of resulting list. + * + * @return the first result of resulting list + * @see #singleResult() + * @see #listResult() + */ + public C firstResult() { + C result = null; + List<C> results = listResult(); + if (!CollectionUtils.isEmpty(results)) { + result = results.get(0); + } + return result; + } + } Modified: jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/query/QueryWrapper.java =================================================================== --- jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/query/QueryWrapper.java 2010-12-29 16:32:38 UTC (rev 447) +++ jpa2-validation/trunk/jsr317-jpa2/src/main/java/org/nuiton/sandbox/jsr317/jpa2/query/QueryWrapper.java 2010-12-29 17:31:40 UTC (rev 448) @@ -24,8 +24,8 @@ * QueryWrapper is used to contain instances used to create a query with Criteria Api. {@link #base()} is the main * element where QL statements are called (WHERE, FROM, ORDER_BY, ...), then you need {@link #builder()} to create * predicate expressions to use in criteria. The {@link #root()} element is also available depends on E type which - * extend the {@link BaseEntityImpl} type. Then you can retrieve {@link TypedQuery} based on criteria created using - * {@link #computeCriteria()} method or {@link #query()} if already defined. + * extend the {@link BaseEntityImpl} type. Then you can create {@link TypedQuery} based on current criteria using + * {@link #computeCriteria()} method. * <p/> * The simple way to use this wrapper is to add predicates using {@link #addPredicate(Predicate)} method and then * execute the query retrieved using {@link #computeCriteria()}. Each predicate could be created using {@link @@ -42,8 +42,8 @@ * ) * ); * <p/> - * // Calling query() the first time will compute the criteria, each next calling will keep the same query - * List<Customer> customers = wrapper.query().getResultList(); + * // Calling computeCriteria() will compute the criteria to create the TypedQuery to execute + * List<Customer> customers = wrapper.computeCriteria().getResultList(); * </pre> * <p/> * Created on 18 nov. 2010 @@ -94,11 +94,6 @@ protected Map<Class<?>, Path<?>> paths; /** - * Resulting query to execute based on result class - */ - protected TypedQuery<R> query; - - /** * List of current predicates to add to the query (on {@link #computeCriteria()} ) */ protected List<Predicate> predicates; @@ -156,7 +151,7 @@ * Set the base asbtractQuery to use it for all operations (from, where, ...). You can set a {@link Subquery} as * base element to manipulate in into the wrapper. All methods on predicates and path will be available but if you * need a criteria you have to retrieve it from the main query otherwise it occurs some errors on {@link - * #computeCriteria()} method or {@link #query()}. If you use {@link #addPredicate(Predicate)} method you need to + * #computeCriteria()} method. If you use {@link #addPredicate(Predicate)} method you need to * manually compute all predicates at the end of the treatment using {@link #computePredicates()}. * * @param base Base {@link AbstractQuery} to set, generally a {@link Subquery} @@ -223,39 +218,22 @@ } /** - * Create a TypedQuery from the current criteria. Predicate list will be added to the where of the query. You can - * also call {@link #query()} to avoid computing criteria each time and so retrieve the current query. + * Create a TypedQuery from the current criteria. Predicate list will be added to the where of the query. * * @return a TypedQuery * @throws NullPointerException if criteria is null, must use {@link #criteria()} method before compute it. */ public TypedQuery<R> computeCriteria() { computePredicates(); - query = entityManager.createQuery(criteria); + TypedQuery<R> query = entityManager.createQuery(criteria); return query; } /** - * Retrieve the current TypedQuery. The query will be computed once based on current criteria if it's not manually - * done using {@link #computeCriteria()}. - * - * @return the current TypedQuery - * @see #computeCriteria() - */ - public TypedQuery<R> query() { - if (query == null) { - computeCriteria(); - } - return query; - } - - /** * Add a predicate to the current list. This predicate will be add to the where clause of the query on {@link - * #computePredicates()}. The computing will be automatically done on query execution with {@link #query()} or - * {@link #computeCriteria()}. + * #computePredicates()}. The computing is also automatic on {@link #computeCriteria()} to execute the query. * * @param predicate New predicate to add to the query - * @see #query() */ public void addPredicate(Predicate predicate) { if (predicates == null) { @@ -273,7 +251,7 @@ * @param <T> Type of the property * @return Predicate constructed this way (already added to the query) */ - public <T> Predicate addEqual(Path<? extends T> propertyPath, T value) { + public <T> Predicate addEqualPredicate(Path<? extends T> propertyPath, T value) { Predicate equalPredicate; @@ -297,8 +275,8 @@ * @param <T> Type of the property * @return Predicate constructed this way (already added to the query) */ - public <T> Predicate addEqual(String property, T value) { - return addEqual(root().<T>get(property), value); + public <T> Predicate addEqualPredicate(String property, T value) { + return addEqualPredicate(root().<T>get(property), value); } /** @@ -307,7 +285,7 @@ * @param predicates List of predicate to add as OR predicate * @return Predicate constructed this way (already added to the query) */ - public Predicate addOr(List<Predicate> predicates) { + public Predicate addOrPredicate(List<Predicate> predicates) { Predicate orPredicate = builder().or(predicates.toArray(new Predicate[predicates.size()])); addPredicate(orPredicate); return orPredicate;