blob: 1dfcaf65852726caec9268e7a2327fadf0e487a2 [file] [log] [blame]
/*
* 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);
}
}