From fa0c0f2c438728be001db476c6b589d51138a0bc Mon Sep 17 00:00:00 2001 From: "Daniel Cunha (soro)" Date: Tue, 26 May 2015 16:52:14 -0300 Subject: [PATCH] Fixed: DELTASPIKE-911 Criteria API - Add support for accept multiple columns in orderBy --- .../data/impl/criteria/QueryCriteria.java | 11 ++- .../data/impl/criteria/processor/OrderBy.java | 82 ++++++++++++++++--- .../data/impl/criteria/CriteriaTest.java | 15 ++++ .../service/SimpleCriteriaRepository.java | 7 ++ 4 files changed, 102 insertions(+), 13 deletions(-) diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java index 79ffbedd5..89e6b4298 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java @@ -81,6 +81,7 @@ public class QueryCriteria implements Criteria private final boolean ignoreNull = true; private boolean distinct = false; + private final OrderBy orderByProcessor = new OrderBy(); private final List> builders = new LinkedList>(); private final List> processors = new LinkedList>(); private final List> selections = new LinkedList>(); @@ -241,14 +242,14 @@ public Criteria fetch(PluralAttribute att, JoinTyp @Override public

Criteria orderAsc(SingularAttribute att) { - add(new OrderBy(att, OrderDirection.ASC)); + addOrderBy(att, OrderDirection.ASC); return this; } @Override public

Criteria orderDesc(SingularAttribute att) { - add(new OrderBy(att, OrderDirection.DESC)); + addOrderBy(att, OrderDirection.DESC); return this; } @@ -294,6 +295,7 @@ public List predicates(CriteriaBuilder builder, Path path) void applyProcessors(CriteriaQuery query, CriteriaBuilder builder, From from) { + orderByProcessor.process(query, builder, from); for (QueryProcessor proc : processors) { proc.process(query, builder, from); @@ -335,6 +337,11 @@ private void add(QueryProcessor proc) processors.add(proc); } + private void addOrderBy(SingularAttribute att, OrderDirection orderDirection) + { + orderByProcessor.add(att, orderDirection); + } + private Selection[] prepareSelections(CriteriaQuery query, CriteriaBuilder builder, From root) { List> result = new ArrayList>(selections.size()); diff --git a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/processor/OrderBy.java b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/processor/OrderBy.java index 822832078..28ec31c9d 100644 --- a/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/processor/OrderBy.java +++ b/deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/processor/OrderBy.java @@ -20,34 +20,94 @@ import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Order; import javax.persistence.criteria.Path; import javax.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.builder.OrderDirection; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + public class OrderBy implements QueryProcessor

{ - private final SingularAttribute att; - private final OrderDirection dir; + private final Set orderByDefinitions = new HashSet(); - public OrderBy(SingularAttribute att, OrderDirection dir) + public void add(SingularAttribute att, OrderDirection dir) { - this.att = att; - this.dir = dir; + orderByDefinitions.add(new OrderByDefinition(att, dir)); } @Override public void process(CriteriaQuery query, CriteriaBuilder builder, Path

path) { - switch (dir) + List orders = new ArrayList(); + for (OrderByDefinition orderByDefinition : orderByDefinitions) { - case ASC: - query.orderBy(builder.asc(path.get(att))); - break; - default: - query.orderBy(builder.desc(path.get(att))); + switch (orderByDefinition.getDir()) + { + case ASC: + orders.add(builder.asc(path.get(orderByDefinition.getAtt()))); + break; + default: + orders.add(builder.desc(path.get(orderByDefinition.getAtt()))); + } } + query.orderBy(orders); } + private class OrderByDefinition + { + private final SingularAttribute att; + private final OrderDirection dir; + + public OrderByDefinition(SingularAttribute att, OrderDirection dir) + { + this.att = att; + this.dir = dir; + } + + public SingularAttribute getAtt() + { + return att; + } + + public OrderDirection getDir() + { + return dir; + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + OrderByDefinition that = (OrderByDefinition) o; + + if (att != null ? !att.equals(that.att) : that.att != null) + { + return false; + } + return dir == that.dir; + + } + + @Override + public int hashCode() + { + int result = att != null ? att.hashCode() : 0; + result = 31 * result + (dir != null ? dir.hashCode() : 0); + return result; + } + } } diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java index 44a3f3273..5fa18bfe4 100644 --- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java +++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java @@ -420,6 +420,21 @@ public void should_query_with_att_from_mapped_super() assertEquals(superName, result.getSuperName()); } + @Test + public void should_apply_multiply_orderby() + { + // given + createSimple("a", 1); + createSimple("b", 2); + + // when + final List orderByNameAndCounter = repo.findOrderByNameAndCounter(); + + // then + assertEquals(new Integer(2), orderByNameAndCounter.get(0).getCounter()); + assertEquals(new Integer(1), orderByNameAndCounter.get(1).getCounter()); + } + @Override protected EntityManager getEntityManager() { diff --git a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java index 35c87fd47..c5b3389d7 100644 --- a/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java +++ b/deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java @@ -121,4 +121,11 @@ public List queryWithSelectAttributes(String name) .getResultList(); } + public List findOrderByNameAndCounter() { + return criteria() + .orderAsc(Simple_.name) + .orderDesc(Simple_.counter) + .getResultList(); + } + }