| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openjpa.persistence.criteria; |
| |
| import static javax.persistence.metamodel.Type.PersistenceType.EMBEDDABLE; |
| import static javax.persistence.metamodel.Type.PersistenceType.ENTITY; |
| |
| import java.math.BigDecimal; |
| import java.util.List; |
| import java.util.Set; |
| |
| import javax.persistence.Embeddable; |
| import javax.persistence.Entity; |
| import javax.persistence.Parameter; |
| import javax.persistence.Query; |
| import javax.persistence.Tuple; |
| import javax.persistence.criteria.CriteriaQuery; |
| import javax.persistence.criteria.Expression; |
| import javax.persistence.criteria.Join; |
| import javax.persistence.criteria.JoinType; |
| import javax.persistence.criteria.ListJoin; |
| import javax.persistence.criteria.MapJoin; |
| import javax.persistence.criteria.Predicate; |
| import javax.persistence.criteria.Root; |
| import javax.persistence.criteria.SetJoin; |
| import javax.persistence.criteria.Subquery; |
| import javax.persistence.metamodel.EmbeddableType; |
| import javax.persistence.metamodel.EntityType; |
| import javax.persistence.metamodel.ManagedType; |
| import javax.persistence.metamodel.Metamodel; |
| import javax.persistence.metamodel.SetAttribute; |
| |
| import org.apache.openjpa.persistence.test.AllowFailure; |
| |
| public class TestMetaModelTypesafeCriteria extends CriteriaTest { |
| protected EntityType<Account> account_ = null; |
| protected EmbeddableType<Address> address_ = null; |
| protected EmbeddableType<Contact> contact_ = null; |
| protected EntityType<Course> course_ = null; |
| protected EntityType<CreditCard> creditCard_ = null; |
| protected EntityType<Customer> customer_ = null; |
| protected EntityType<Department> department_ = null; |
| protected EntityType<Employee> employee_ = null; |
| protected EntityType<Exempt> exempt_ = null; |
| protected EntityType<Item> item_ = null; |
| protected EntityType<LineItem> lineItem_ = null; |
| protected EntityType<Manager> manager_ = null; |
| protected EntityType<Movie> movie_ = null; |
| protected EntityType<Order> order_ = null; |
| protected EntityType<Person> person_ = null; |
| protected EntityType<Phone> phone_ = null; |
| protected EntityType<Photo> photo_ = null; |
| protected EntityType<Product> product_ = null; |
| protected EntityType<Semester> semester_ = null; |
| protected EntityType<Student> student_ = null; |
| protected EntityType<TransactionHistory> transactionHistory_ = null; |
| protected EntityType<VideoStore> videoStore_ = null; |
| |
| @Override |
| public void setUp() throws Exception { |
| super.setUp(); |
| |
| Metamodel mm = em.getMetamodel(); |
| account_ = mm.entity(Account.class); |
| address_ = mm.embeddable(Address.class); |
| assertNotNull(address_); |
| contact_ = mm.embeddable(Contact.class); |
| course_ = mm.entity(Course.class); |
| creditCard_ = mm.entity(CreditCard.class); |
| customer_ = mm.entity(Customer.class); |
| department_ = mm.entity(Department.class); |
| employee_ = mm.entity(Employee.class); |
| exempt_ = mm.entity(Exempt.class); |
| item_ = mm.entity(Item.class); |
| lineItem_ = mm.entity(LineItem.class); |
| manager_ = mm.entity(Manager.class); |
| movie_ = mm.entity(Movie.class); |
| order_ = mm.entity(Order.class); |
| person_ = mm.entity(Person.class); |
| phone_ = mm.entity(Phone.class); |
| photo_ = mm.entity(Photo.class); |
| product_ = mm.entity(Product.class); |
| semester_ = mm.entity(Semester.class); |
| student_ = mm.entity(Student.class); |
| transactionHistory_ = mm.entity(TransactionHistory.class); |
| videoStore_ = mm.entity(VideoStore.class); |
| } |
| |
| public void testEntityEmbeddableTest() { |
| Metamodel mm = em.getMetamodel(); |
| |
| assertEquals(mm.managedType(Account.class).getPersistenceType(), ENTITY); |
| assertEquals(mm.managedType(Address.class).getPersistenceType(), EMBEDDABLE); |
| |
| assertNotNull(mm.entity(Account.class)); |
| assertNotNull(mm.embeddable(Address.class)); |
| |
| try { |
| mm.entity(Address.class); |
| fail("Expecting IllegalArgumentException"); |
| } catch (IllegalArgumentException iaex) { |
| } |
| try { |
| mm.embeddable(Account.class); |
| fail("Expecting IllegalArgumentException"); |
| } catch (IllegalArgumentException iaex) { |
| } |
| |
| int numEntity = 0; |
| int numEmbeddables = 0; |
| for (Class<?> clz : getDomainClasses()) { |
| if (clz.getAnnotation(Embeddable.class) != null) { |
| ++numEmbeddables; |
| } else if (clz.getAnnotation(Entity.class) != null) { |
| ++numEntity; |
| } |
| } |
| Set<EmbeddableType<?>> embs = mm.getEmbeddables(); |
| assertEquals(embs.size(), numEmbeddables); |
| Set<EntityType<?>> ents = mm.getEntities(); |
| assertEquals(ents.size(), numEntity); |
| Set<ManagedType<?>> metaTypes = mm.getManagedTypes(); |
| assertEquals(metaTypes.size(), numEntity + numEmbeddables); |
| } |
| |
| public void testStringEqualExpression() { |
| String jpql = "select c from Customer c " |
| + "where c.name='Autowest Toyota'"; |
| |
| CriteriaQuery q = cb.createQuery(); |
| Root<Customer> customer = q.from(Customer.class); |
| q.select(customer) |
| .where(cb.equal( |
| customer.get(customer_.getSingularAttribute("name", String.class)), |
| "Autowest Toyota")); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testSetAndListJoins() { |
| String jpql = "SELECT c.name FROM Customer c " |
| + "JOIN c.orders o JOIN o.lineItems i " |
| + "WHERE i.product.productType = 'printer'"; |
| |
| CriteriaQuery q = cb.createQuery(); |
| Root<Customer> c = q.from(Customer.class); |
| SetJoin<Customer, Order> o = c.join(customer_.getSet("orders", |
| Order.class)); |
| ListJoin<Order, LineItem> i = o.join(order_.getList("lineItems", |
| LineItem.class)); |
| q.select(c.get(Customer_.name)).where( |
| cb.equal(i.get(lineItem_.getSingularAttribute("product", Product.class)) |
| .get(product_.getSingularAttribute("productType", String.class)), |
| "printer")); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testLeftSetJoin() { |
| String jpql = "SELECT c FROM Customer c " |
| + "LEFT JOIN c.orders o " |
| + "WHERE c.status = 1"; |
| |
| CriteriaQuery<Customer> q = cb.createQuery(Customer.class); |
| Root<Customer> c = q.from(Customer.class); |
| SetJoin<Customer, Order> o = c.join(customer_.getSet("orders", |
| Order.class), JoinType.LEFT); |
| q.where(cb.equal( |
| c.get(customer_.getSingularAttribute("status", Integer.class)), |
| 1)); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testFetchJoins() { |
| String jpql = "SELECT d FROM Department d LEFT JOIN FETCH d.employees " |
| + "WHERE d.deptNo = 1"; |
| CriteriaQuery q = cb.createQuery(); |
| Root<Department> d = q.from(Department.class); |
| d.fetch(department_.getSet("employees", Employee.class), JoinType.LEFT); |
| q.where( |
| cb.equal(d.get(department_ |
| .getSingularAttribute("deptNo", Integer.class)), 1)).select(d); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| @AllowFailure(message="This is regression.") |
| public void testPathNavigation() { |
| String jpql = "SELECT p.vendor FROM Employee e " |
| + "JOIN e.contactInfo.phones p " |
| + "WHERE e.contactInfo.address.zipCode = '95054'"; |
| |
| |
| CriteriaQuery<String> q = cb.createQuery(String.class); |
| Root<Employee> e = q.from(Employee.class); |
| Join<Contact, Phone> p = e.join(employee_.getSingularAttribute("contactInfo", Contact.class)) |
| .join(contact_.getList("phones", Phone.class)); |
| q.where(cb.equal(e.get(employee_.getSingularAttribute("contactInfo", Contact.class)) |
| .get(contact_.getSingularAttribute("address", Address.class)) |
| .get(address_.getSingularAttribute("zipCode", String.class)), |
| "95054")); |
| q.select(p.get(phone_.getSingularAttribute("vendor", String.class))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testKeyPathNavigation() { |
| String jpql = "SELECT i.name, p FROM Item i JOIN i.photos p WHERE KEY(p) LIKE '%egret%'"; |
| |
| CriteriaQuery<Tuple> q = cb.createTupleQuery(); |
| Root<Item> i = q.from(Item.class); |
| MapJoin<Item, String, Photo> p = i.join(item_.getMap("photos", String.class, Photo.class)); |
| q.multiselect(i.get(item_.getSingularAttribute("name", String.class)), p) |
| .where(cb.like(p.key(), "%egret%")); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testIndexExpression() { |
| String jpql = "SELECT t FROM CreditCard c JOIN c.transactionHistory t " |
| + "WHERE c.customer.accountNum = 321987 AND INDEX(t) BETWEEN 0 " |
| + "AND 9"; |
| |
| CriteriaQuery<TransactionHistory> cq = cb.createQuery(TransactionHistory.class); |
| Root<CreditCard> c = cq.from(CreditCard.class); |
| ListJoin<CreditCard, TransactionHistory> t = c.join(creditCard_.getList("transactionHistory", |
| TransactionHistory.class)); |
| Predicate p1 = cb.equal( |
| c.get(creditCard_.getSingularAttribute("customer", Customer.class)) |
| .get(customer_.getSingularAttribute("accountNum", long.class)), 321987); |
| Predicate p2 = cb.between(t.index(), 0, 9); |
| cq.select(t).where(p1,p2); |
| |
| assertEquivalence(cq, jpql); |
| } |
| |
| public void testIsEmptyExpressionOnJoin() { |
| String jpql = "SELECT o FROM Order o WHERE o.lineItems IS EMPTY"; |
| CriteriaQuery<Order> q = cb.createQuery(Order.class); |
| Root<Order> o = q.from(Order.class); |
| Expression<LineItem> lineItems = o.get("lineItems").as(LineItem.class); |
| q.where(cb.isEmpty(lineItems.as(List.class))); |
| q.select(o); |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testFunctionalExpressionInProjection() { |
| String jpql = "SELECT o.quantity, o.totalCost*1.08 AS taxedCost, " |
| + "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a " |
| + "WHERE a.state = 'CA' AND a.county = 'Santa Clara'"; |
| |
| CriteriaQuery<Tuple> q = cb.createTupleQuery(); |
| Root<Customer> c = q.from(Customer.class); |
| Join<Customer, Order> o = c.join(customer_.getSet("orders", Order.class)); |
| Join<Customer, Address> a = c.join(customer_.getSingularAttribute("address", Address.class)); |
| Expression<Double> taxedCost = (Expression<Double>)cb.prod(o.get(order_.getSingularAttribute("totalCost", |
| Double.class)), 1.08).alias("taxedCost"); |
| q.where(cb.equal(a.get(address_.getSingularAttribute("state", String.class)), "CA"), |
| cb.equal(a.get(address_.getSingularAttribute("county", String.class)), "Santa Clara")); |
| q.multiselect(o.get(order_.getSingularAttribute("quantity", Integer.class)), |
| taxedCost, |
| a.get(address_.getSingularAttribute("zipCode", String.class))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testTypeExpression() { |
| String jpql = "SELECT TYPE(e) FROM Employee e WHERE TYPE(e) <> Exempt"; |
| CriteriaQuery q = cb.createQuery(); |
| Root<Employee> emp = q.from(Employee.class); |
| q.select(emp.type()).where(cb.notEqual(emp.type(), Exempt.class)); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testJoinAndIndexExpression() { |
| String jpql = "SELECT w.name FROM Course c JOIN c.studentWaitList w " |
| + "WHERE c.name = 'Calculus' AND INDEX(w) = 0"; |
| |
| CriteriaQuery<String> q = cb.createQuery(String.class); |
| Root<Course> course = q.from(Course.class); |
| ListJoin<Course, Student> w = course.join(course_.getList("studentWaitList", Student.class)); |
| q.where(cb.equal(course.get(course_.getSingularAttribute("name", String.class)), "Calculus"), |
| cb.equal(w.index(), 0)) |
| .select(w.get(student_.getSingularAttribute("name", String.class))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testAggregateExpressionInProjection() { |
| String jpql = "SELECT SUM(i.price) " |
| + "FROM Order o JOIN o.lineItems i JOIN o.customer c " |
| + "WHERE c.lastName = 'Smith' AND c.firstName = 'John'"; |
| CriteriaQuery q = cb.createQuery(); |
| Root<Order> o = q.from(Order.class); |
| Join<Order, LineItem> i = o.join(order_.getList("lineItems", |
| LineItem.class)); |
| Join<Order, Customer> c = o.join(order_.getSingularAttribute("customer", |
| Customer.class)); |
| q.where(cb.equal(c.get(customer_.getSingularAttribute("lastName", String.class)), "Smith"), |
| cb.equal(c.get(customer_.getSingularAttribute("firstName", String.class)), "John")); |
| q.select(cb.sum(i.get(lineItem_.getSingularAttribute("price", Double.class)))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testSizeExpressionInProjection() { |
| String jpql = "SELECT SIZE(d.employees) FROM Department d " |
| + "WHERE d.name = 'Sales'"; |
| |
| CriteriaQuery q = cb.createQuery(); |
| Root<Department> d = q.from(Department.class); |
| q.where(cb.equal( |
| d.get(department_.getSingularAttribute("name", String.class)), |
| "Sales")); |
| SetAttribute<Department, Employee> employees = |
| department_.getDeclaredSet("employees", Employee.class); |
| q.select(cb.size(d.get(employees))); |
| |
| assertEquivalence(q, jpql); |
| |
| } |
| |
| public void testCaseExpression() { |
| String jpql = "SELECT e.name, " |
| + "CASE WHEN e.rating = 1 THEN e.salary * 1.1 " |
| + "WHEN e.rating = 2 THEN e.salary * 1.2 ELSE e.salary * 1.01 END " |
| + "FROM Employee e WHERE e.department.name = 'Engineering'"; |
| |
| CriteriaQuery<?> q = cb.createQuery(); |
| Root<Employee> e = q.from(Employee.class); |
| q.where(cb.equal(e.get( |
| employee_.getSingularAttribute("department", Department.class)) |
| .get(department_.getSingularAttribute("name", String.class)), |
| "Engineering")); |
| q.multiselect(e.get(employee_.getSingularAttribute("name", String.class)), |
| cb.selectCase().when( |
| cb.equal(e.get(employee_.getSingularAttribute("rating", Integer.class)), 1), |
| cb.prod(e.get(employee_.getSingularAttribute("salary", Long.class)), 1.1)).when( |
| cb.equal(e.get(employee_.getSingularAttribute("rating", Integer.class)), 2), |
| cb.prod(e.get(employee_.getSingularAttribute("salary", Long.class)), 1.2)).otherwise( |
| cb.prod(e.get(employee_.getSingularAttribute("salary", Long.class)), 1.01))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testMemberOfExpression() { |
| String jpql = "SELECT p FROM Person p where 'Joe' MEMBER OF p.nickNames"; |
| |
| CriteriaQuery<?> q = cb.createQuery(); |
| Root<Person> p = q.from(Person.class); |
| q.multiselect(p).where(cb.isMember(cb.literal("Joe"), |
| p.get(person_.getDeclaredSet("nickNames", String.class)))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testParameters() { |
| String jpql = "SELECT c FROM Customer c Where c.status = :stat"; |
| CriteriaQuery<?> q = cb.createQuery(); |
| Root<Customer> c = q.from(Customer.class); |
| Parameter<Integer> param = cb.parameter(Integer.class, "stat"); |
| q.multiselect(c).where(cb.equal( |
| c.get(customer_.getSingularAttribute("status", Integer.class)), param)); |
| |
| assertEquivalence(new QueryDecorator() { |
| @Override |
| public void decorate(Query q) { |
| q.setParameter("stat", 1); |
| } |
| }, q, jpql); |
| } |
| |
| public void testKeyExpressionInSelectList() { |
| String jpql = "SELECT v.location.street, KEY(i).title, VALUE(i) " |
| + "FROM VideoStore v JOIN v.videoInventory i " |
| + "WHERE v.location.zipCode = '94301' AND VALUE(i) > 0"; |
| |
| CriteriaQuery<?> q = cb.createQuery(); |
| Root<VideoStore> v = q.from(VideoStore.class); |
| MapJoin<VideoStore, Movie, Integer> i = v.join(videoStore_.getMap("videoInventory", Movie.class,Integer.class)); |
| q.where(cb.equal(v.get(videoStore_.getSingularAttribute("location", Address.class)) |
| .get(address_.getSingularAttribute("zipCode", String.class)), "94301"), |
| cb.gt(i.value(), 0)); |
| q.multiselect(v.get(videoStore_.getSingularAttribute("location", Address.class)) |
| .get(address_.getSingularAttribute("street", String.class)), |
| i.key().get(movie_.getSingularAttribute("title", String.class)), |
| i.value()); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testConstructorInSelectList() { |
| String jpql = "SELECT NEW CustomerDetails(c.id, c.status, o.quantity) " |
| + "FROM Customer c JOIN c.orders o WHERE o.quantity > 100"; |
| |
| CriteriaQuery<CustomerDetails> q = cb.createQuery(CustomerDetails.class); |
| Root<Customer> c = q.from(Customer.class); |
| SetJoin<Customer, Order> o = c.join( |
| customer_.getSet("orders", Order.class)); |
| q.where(cb.gt(o.get(order_.getSingularAttribute("quantity", Integer.class)), |
| 100)); |
| q.select(cb.construct(CustomerDetails.class, |
| c.get(customer_.getSingularAttribute("id", Long.class)), |
| c.get(customer_.getSingularAttribute("status", Integer.class)), |
| o.get(order_.getSingularAttribute("quantity", Integer.class)))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testUncorrelatedSubqueryWithAggregateProjection() { |
| String jpql = "SELECT goodCustomer FROM Customer goodCustomer WHERE " |
| + "goodCustomer.balanceOwed < (SELECT AVG(c.balanceOwed) FROM " |
| + "Customer c)"; |
| CriteriaQuery<?> q = cb.createQuery(); |
| Root<Customer> goodCustomer = q.from(Customer.class); |
| Subquery<Double> sq = q.subquery(Double.class); |
| Root<Customer> c = sq.from(Customer.class); |
| q.where(cb.lt(goodCustomer.get(customer_.getSingularAttribute("balanceOwed", |
| Integer.class)), sq.select(cb.avg(c.get(customer_.getSingularAttribute( |
| "balanceOwed", Integer.class)))))); |
| q.multiselect(goodCustomer); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testSubqueryWithExistsClause() { |
| String jpql = "SELECT DISTINCT emp FROM Employee emp WHERE EXISTS (" |
| + "SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp = " |
| + "emp.spouse)"; |
| CriteriaQuery<Employee> q = cb.createQuery(Employee.class); |
| Root<Employee> emp = q.from(Employee.class); |
| Subquery<Employee> sq = q.subquery(Employee.class); |
| Root<Employee> spouseEmp = sq.from(Employee.class); |
| sq.select(spouseEmp); |
| sq.where(cb.equal(spouseEmp, emp.get(employee_.getSingularAttribute("spouse", Employee.class)))); |
| q.where(cb.exists(sq)); |
| q.distinct(true); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testSubqueryWithAllClause() { |
| String jpql = "SELECT emp FROM Employee emp WHERE emp.salary > ALL (" |
| + "SELECT m.salary FROM Manager m WHERE m.department =" |
| + " emp.department)"; |
| |
| CriteriaQuery<Employee> q = cb.createQuery(Employee.class); |
| Root<Employee> emp = q.from(Employee.class); |
| |
| Subquery<BigDecimal> sq = q.subquery(BigDecimal.class); |
| Root<Manager> m = sq.from(Manager.class); |
| sq.select(m.get(manager_.getSingularAttribute("salary", BigDecimal.class))); |
| sq.where(cb.equal(m.get(manager_.getSingularAttribute("department", |
| Department.class)), emp.get(employee_.getSingularAttribute( |
| "department", Department.class)))); |
| q.where(cb.gt(emp.get(employee_.getSingularAttribute("salary", Long.class)), cb |
| .all(sq))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testCorrelatedSubqueryWithCount() { |
| String jpql = "SELECT c FROM Customer c WHERE " |
| + "(SELECT COUNT(o) FROM c.orders o) > 10"; |
| CriteriaQuery<Customer> q = cb.createQuery(Customer.class); |
| Root<Customer> c1 = q.from(Customer.class); |
| Subquery<Long> sq3 = q.subquery(Long.class); |
| Root<Customer> c2 = sq3.correlate(c1); |
| Join<Customer, Order> o = c2.join(customer_.getSet("orders", |
| Order.class)); |
| q.where(cb.gt(sq3.select(cb.count(o)), 10)); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testCorrelatedSubqueryWithJoin() { |
| String jpql = "SELECT o FROM Order o WHERE 10000 < ALL (" |
| + "SELECT a.balance FROM o.customer c JOIN c.accounts a)"; |
| |
| CriteriaQuery<Order> q = cb.createQuery(Order.class); |
| Root<Order> o = q.from(Order.class); |
| |
| Subquery<Integer> sq = q.subquery(Integer.class); |
| Root<Order> o2 = sq.correlate(o); |
| Join<Order, Customer> c = o2.join(order_.getSingularAttribute("customer", |
| Customer.class)); |
| Join<Customer, Account> a = c.join(customer_.getList("accounts", |
| Account.class)); |
| sq.select(a.get(account_.getSingularAttribute("balance", Integer.class))); |
| q.where(cb.lt(cb.literal(10000), cb.all(sq))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testCorrelatedSubqueryWithAllClause() { |
| String jpql = "SELECT o FROM Order o JOIN o.customer c " |
| + "WHERE 10000 < ALL (SELECT a.balance FROM c.accounts a)"; |
| |
| CriteriaQuery<Order> q = cb.createQuery(Order.class); |
| Root<Order> o = q.from(Order.class); |
| |
| Join<Order, Customer> c = o.join(Order_.customer); |
| Subquery<Integer> sq = q.subquery(Integer.class); |
| Join<Order, Customer> csq = sq.correlate(c); |
| Join<Customer, Account> a = csq.join(customer_.getList("accounts", |
| Account.class)); |
| sq.select(a.get(account_.getSingularAttribute("balance", Integer.class))); |
| q.where(cb.lt(cb.literal(10000), cb.all(sq))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testGroupByAndHaving() { |
| String jpql = "SELECT c.status, AVG(c.filledOrderCount), COUNT(c) FROM " |
| + "Customer c GROUP BY c.status HAVING c.status IN (1, 2)"; |
| |
| CriteriaQuery<?> q = cb.createQuery(); |
| Root<Customer> c = q.from(Customer.class); |
| q.groupBy(c.get(customer_.getSingularAttribute("status", Integer.class))); |
| q.having(cb.in(c.get(customer_.getSingularAttribute("status", Integer.class))) |
| .value(1).value(2)); |
| q.multiselect(c.get(customer_.getSingularAttribute("status", Integer.class)), cb |
| .avg(c.get(customer_.getSingularAttribute("filledOrderCount", |
| Integer.class))), cb.count(c)); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testOrderingByExpressionNotIncludedInSelection() { |
| String jpql = "SELECT o FROM Customer c " |
| + "JOIN c.orders o JOIN c.address a " |
| + "WHERE a.state = 'CA' " |
| + "ORDER BY o.quantity DESC, o.totalCost"; |
| |
| CriteriaQuery<?> q = cb.createQuery(); |
| Root<Customer> c = q.from(Customer.class); |
| SetJoin<Customer, Order> o = c.join(customer_.getSet("orders", |
| Order.class)); |
| Join<Customer, Address> a = c.join(customer_.getSingularAttribute("address", |
| Address.class)); |
| q.where(cb.equal( |
| a.get(address_.getSingularAttribute("state", String.class)), |
| "CA")); |
| q.orderBy( |
| cb.desc(o.get(order_.getSingularAttribute("quantity", Integer.class))), |
| cb.asc(o.get(order_.getSingularAttribute("totalCost", Double.class)))); |
| q.multiselect(o); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testOrderingByExpressionIncludedInSelection() { |
| String jpql = "SELECT o.quantity, a.zipCode FROM Customer c " |
| + "JOIN c.orders o JOIN c.address a " |
| + "WHERE a.state = 'CA' " |
| + "ORDER BY o.quantity, a.zipCode"; |
| |
| CriteriaQuery<?> q = cb.createQuery(); |
| Root<Customer> c = q.from(Customer.class); |
| Join<Customer, Order> o = c.join(customer_.getSet("orders", |
| Order.class)); |
| Join<Customer, Address> a = c.join(customer_.getSingularAttribute("address", |
| Address.class)); |
| q.where(cb.equal( |
| a.get(address_.getSingularAttribute("state", String.class)), |
| "CA")); |
| q.orderBy(cb |
| .asc(o.get(order_.getSingularAttribute("quantity", Integer.class))), |
| cb.asc(a.get(address_.getSingularAttribute("zipCode", String.class)))); |
| q.multiselect(o.get(order_.getSingularAttribute("quantity", Integer.class)), |
| a.get(address_.getSingularAttribute("zipCode", String.class))); |
| |
| assertEquivalence(q, jpql); |
| } |
| |
| public void testOrderingWithNumericalExpressionInSelection() { |
| String jpql = "SELECT o.quantity, o.totalCost * 1.08 AS taxedCost, a.zipCode " |
| + "FROM Customer c JOIN c.orders o JOIN c.address a " |
| + "WHERE a.state = 'CA' AND a.county = 'Santa Clara' " |
| + "ORDER BY o.quantity, taxedCost, a.zipCode"; |
| |
| CriteriaQuery<?> q = cb.createQuery(); |
| Root<Customer> c = q.from(Customer.class); |
| Join<Customer, Order> o = c.join(customer_.getSet("orders", Order.class)); |
| Join<Customer, Address> a = c.join(customer_.getSingularAttribute("address", Address.class)); |
| Expression<Double> taxedCost = (Expression<Double>)cb.prod(o.get(order_.getSingularAttribute("totalCost", |
| Double.class)), 1.08).alias("taxedCost"); |
| q.where(cb.equal(a.get(address_.getSingularAttribute("state", String.class)), "CA"), |
| cb.equal(a.get(address_.getSingularAttribute("county", String.class)), "Santa Clara")); |
| q.orderBy(cb.asc(o.get(order_.getSingularAttribute("quantity", Integer.class))), |
| cb.asc(taxedCost), |
| cb.asc(a.get(address_.getSingularAttribute("zipCode", String.class)))); |
| q.multiselect(o.get(order_.getSingularAttribute("quantity", Integer.class)), |
| taxedCost, |
| a.get(address_.getSingularAttribute("zipCode", String.class))); |
| assertEquivalence(q, jpql); |
| } |
| } |