OPENJPA-1143: Added support for construct(), as(). Metamodel excludes static fields. tests edited to compile against EA3 JPA API.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@789723 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2009-06-30 13:40:17 +00:00
parent 9c6fbcbab3
commit db2082dea4
27 changed files with 826 additions and 821 deletions

View File

@ -18,8 +18,11 @@
*/ */
package org.apache.openjpa.persistence.criteria; package org.apache.openjpa.persistence.criteria;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -53,46 +56,48 @@ import org.apache.openjpa.persistence.test.AllowFailure;
*/ */
public abstract class CriteriaTest extends TestCase { public abstract class CriteriaTest extends TestCase {
protected static OpenJPAEntityManagerFactorySPI emf; protected static OpenJPAEntityManagerFactorySPI emf;
protected static SQLAuditor auditor;
QueryBuilder cb; QueryBuilder cb;
EntityManager em; EntityManager em;
protected List<String> sql = new ArrayList<String>();
protected static Class[] CLASSES = { protected static Class[] CLASSES = {
Account.class, Account.class,
Address.class, Address.class,
A.class, A.class,
B.class, B.class,
CompUser.class, CompUser.class,
Contact.class, Contact.class,
Contractor.class, Contractor.class,
Course.class, Course.class,
CreditCard.class, CreditCard.class,
Customer.class, Customer.class,
C.class, C.class,
Department.class, Department.class,
DependentId.class, DependentId.class,
Dependent.class, Dependent.class,
D.class, D.class,
Employee.class, Employee.class,
Exempt.class, Exempt.class,
FemaleUser.class, FemaleUser.class,
FrequentFlierPlan.class, FrequentFlierPlan.class,
Item.class, Item.class,
LineItem.class, LineItem.class,
Magazine.class, Magazine.class,
MaleUser.class, MaleUser.class,
Manager.class, Manager.class,
Movie.class, Movie.class,
Order.class, Order.class,
Person.class, Person.class,
Phone.class, Phone.class,
Photo.class, Photo.class,
Product.class, Product.class,
Publisher.class, Publisher.class,
Semester.class, Semester.class,
Student.class, Student.class,
TransactionHistory.class, TransactionHistory.class,
Transaction.class, Transaction.class,
VideoStore.class}; VideoStore.class};
protected Class[] getDomainClasses() { protected Class[] getDomainClasses() {
return CLASSES; return CLASSES;
@ -100,6 +105,7 @@ public abstract class CriteriaTest extends TestCase {
public void setUp() { public void setUp() {
if (emf == null) { if (emf == null) {
auditor = new SQLAuditor();
createNamedEMF(getDomainClasses()); createNamedEMF(getDomainClasses());
assertNotNull(emf); assertNotNull(emf);
setDictionary(); setDictionary();
@ -107,6 +113,7 @@ public abstract class CriteriaTest extends TestCase {
em = emf.createEntityManager(); em = emf.createEntityManager();
cb = emf.getQueryBuilder(); cb = emf.getQueryBuilder();
} }
/** /**
* Create an entity manager factory for persistence unit <code>pu</code>. * Create an entity manager factory for persistence unit <code>pu</code>.
* Put {@link #CLEAR_TABLES} in * Put {@link #CLEAR_TABLES} in
@ -120,13 +127,12 @@ public abstract class CriteriaTest extends TestCase {
Map<Object,Object> map = new HashMap<Object,Object>(); Map<Object,Object> map = new HashMap<Object,Object>();
map.put("openjpa.jdbc.SynchronizeMappings", map.put("openjpa.jdbc.SynchronizeMappings",
"buildSchema(ForeignKeys=true," "buildSchema(ForeignKeys=true,"
+ "SchemaAction='add,deleteTableContents')"); + "SchemaAction='add')");
map.put("openjpa.jdbc.QuerySQLCache", "false"); map.put("openjpa.jdbc.QuerySQLCache", "false");
map.put("openjpa.DynamicEnhancementAgent", "false"); map.put("openjpa.DynamicEnhancementAgent", "false");
map.put("openjpa.RuntimeUnenhancedClasses", "unsupported"); map.put("openjpa.RuntimeUnenhancedClasses", "unsupported");
map.put("openjpa.Compatibility", "QuotedNumbersInQueries=true"); map.put("openjpa.Compatibility", "QuotedNumbersInQueries=true");
map.put("openjpa.jdbc.JDBCListeners", map.put("openjpa.jdbc.JDBCListeners", new JDBCListener[] { auditor });
new JDBCListener[] { new Listener() });
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
for (Class<?> c : types) { for (Class<?> c : types) {
@ -135,17 +141,11 @@ public abstract class CriteriaTest extends TestCase {
buf.append(c.getName()); buf.append(c.getName());
} }
map.put("openjpa.MetaDataFactory", map.put("openjpa.MetaDataFactory", "jpa(Types=" + buf.toString() + ")");
"jpa(Types=" + buf.toString() + ")");
Map config = new HashMap(System.getProperties()); Map<Object,Object> config = new HashMap<Object,Object>(System.getProperties());
config.putAll(map); config.putAll(map);
emf = (OpenJPAEntityManagerFactorySPI) emf = (OpenJPAEntityManagerFactorySPI) Persistence.createEntityManagerFactory("test", config);
Persistence.createEntityManagerFactory("test", config);
}
public final void tearDown() {
// important: do nothing
} }
void setDictionary() { void setDictionary() {
@ -156,57 +156,36 @@ public abstract class CriteriaTest extends TestCase {
} }
/** /**
* Executes the given CriteriaQuery and JPQL string and compare their * Executes the given CriteriaQuery and JPQL string and compare their respective SQLs for equality.
* respective SQLs for equality.
*/ */
void assertEquivalence(CriteriaQuery c, String jpql, String[] paramNames, void assertEquivalence(CriteriaQuery<?> c, String jpql) {
Object[] params) { assertEquivalence(c, jpql, null);
Query cQ = em.createQuery(c);
for (int i = 0; i < paramNames.length; i++) {
cQ.setParameter(paramNames[i], params[i]);
}
Query jQ = em.createQuery(jpql);
for (int i = 0; i < paramNames.length; i++) {
jQ.setParameter(paramNames[i], params[i]);
}
executeAndAssert(cQ, jQ);
} }
/** /**
* Executes the given CriteriaQuery and JPQL string and compare their * Executes the given CriteriaQuery and JPQL string and compare their respective SQLs for equality.
* respective SQLs for equality. * Sets the supplied parameters, if any.
*/
void assertEquivalence(CriteriaQuery<?> c, String jpql, String[] paramNames, Object[] params) {
Query cQ = em.createQuery(c);
Query jQ = em.createQuery(jpql);
setParameters(cQ, paramNames, params);
setParameters(jQ, paramNames, params);
executeAndCompareSQL(jpql, cQ, jQ);
}
/**
* Executes the given CriteriaQuery and JPQL string and compare their respective SQLs for equality.
*/ */
void assertEquivalence(CriteriaQuery c, String jpql, Object[] params) { void assertEquivalence(CriteriaQuery<?> c, String jpql, Object[] params) {
Query cQ = em.createQuery(c); Query cQ = em.createQuery(c);
for (int i = 0; i < params.length; i++) {
cQ.setParameter(i + 1, params[i]);
}
Query jQ = em.createQuery(jpql); Query jQ = em.createQuery(jpql);
for (int i = 0; i < params.length; i++) { setParameters(cQ, params);
jQ.setParameter(i + 1, params[i]); setParameters(jQ, params);
}
executeAndAssert(cQ, jQ); executeAndCompareSQL(jpql, cQ, jQ);
}
void assertEquivalence(CriteriaQuery c, String jpql) {
executeAndAssert(em.createQuery(c), em.createQuery(jpql));
}
void executeAndAssert(Query cQ, Query jQ) {
List<String>[] sqls = new ArrayList[2];
String jpql = OpenJPAPersistence.cast(jQ).getQueryString();
if (!execute(jpql, cQ, jQ, sqls)) {
fail(sqlReport("Invalid SQL for Criteria",jpql, sqls[0], sqls[1]));
}
assertEquals(sqlReport("Unequal number of SQL ",jpql, sqls[0], sqls[1])
, sqls[0].size(), sqls[1].size());
for (int i = 0; i < sqls[0].size(); i++)
//sqlReport("Wrong SQL at " + i,jpql, sqls[0], sqls[1]),
assertEquals(
sqls[0].get(i), sqls[1].get(i));
} }
/** /**
@ -218,71 +197,82 @@ public abstract class CriteriaTest extends TestCase {
* array. * array.
* @return true if both queries execute successfully. * @return true if both queries execute successfully.
*/ */
boolean execute(String jpql, Query cQ, Query jQ, List<String>[] sqls) { void executeAndCompareSQL(String jpql, Query cQ, Query jQ) {
sql.clear(); List<String> jSQL = null;
List<String> cSQL = null;
try { try {
List jList = jQ.getResultList(); jSQL = executeQueryAndCollectSQL(jQ);
} catch (PersistenceException e) {
e.printStackTrace();
sqls[0] = new ArrayList<String>();
sqls[0].add(extractSQL(e));
fail("Wrong SQL for JPQL :" + jpql + "\r\nSQL :" + sqls[0]);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); StringWriter w = new StringWriter();
fail("Wrong JPQL :" + jpql); e.printStackTrace(new PrintWriter(w));
fail("JPQL " + jpql + " failed to execute\r\n" + w);
} }
sqls[0] = new ArrayList<String>(sql);
sql.clear();
try { try {
List cList = cQ.getResultList(); cSQL = executeQueryAndCollectSQL(cQ);
} catch (PersistenceException e) { } catch (Exception e) {
e.printStackTrace(); StringWriter w = new StringWriter();
sqls[1] = new ArrayList<String>(); e.printStackTrace(new PrintWriter(w));
sqls[1].add(extractSQL(e)); fail("CriteriaQuery corresponding to " + jpql + " failed to execute\r\n" + w);
return false;
} }
sqls[1] = new ArrayList<String>(sql);
return true; printSQL("Target SQL for JPQL", jSQL);
} printSQL("Target SQL for CriteriaQuery", cSQL);
if (jSQL.size() != cSQL.size()) {
printSQL("Target SQL for JPQL", jSQL);
printSQL("Target SQL for CriteriaQuery", cSQL);
assertEquals("No. of SQL generated for JPQL and CriteriaQuery for " + jpql + " is different",
jSQL.size(), cSQL.size());
}
List<String> executeJPQL(String jpql, Map<?,Object> params) { for (int i = 0; i < jSQL.size(); i++) {
sql.clear(); if (!jSQL.get(i).equals(cSQL.get(i))) {
Query q = em.createQuery(jpql); printSQL("Target SQL for JPQL", jSQL);
if (params != null) { printSQL("Target SQL for CriteriaQuery", cSQL);
for (Object key : params.keySet()) { assertEquals(i + "-th SQL for JPQL and CriteriaQuery for " + jpql + " is different",
if (key instanceof String) jSQL.get(i), cSQL.get(i));
q.setParameter(key.toString(), params.get(key));
else if (key instanceof String)
q.setParameter(key.toString(), params.get(key));
else
throw new RuntimeException("Bad Parameter key " + key);
} }
} }
return sql;
} }
String extractSQL(PersistenceException e) { void printSQL(String header, List<String> sqls) {
System.err.println(header);
for (int i = 0; sqls != null && i < sqls.size(); i++) {
System.err.println(i + ":" + sqls.get(i));
}
}
void setParameters(Query q, String[] paramNames, Object[] params) {
for (int i = 0; paramNames != null && i < paramNames.length; i++)
q.setParameter(paramNames[i], params[i]);
}
void setParameters(Query q, Object[] params) {
for (int i = 0; params != null && i < params.length; i++)
q.setParameter(i+1, params[i]);
}
/**
* Execute the given query and return the generated SQL.
* If the query execution fail because the generated SQL is ill-formed, then raised exception should
* carry the ill-formed SQL for diagnosis.
*/
List<String> executeQueryAndCollectSQL(Query q) {
auditor.clear();
try {
List<?> result = q.getResultList();
} catch (Exception e) {
throw new RuntimeException(extractSQL(e), e);
}
assertFalse(auditor.getSQLs().isEmpty());
return auditor.getSQLs();
}
String extractSQL(Exception e) {
Throwable t = e.getCause(); Throwable t = e.getCause();
if (t instanceof ReportingSQLException) if (t instanceof ReportingSQLException)
return ((ReportingSQLException) t).getSQL(); return ((ReportingSQLException) t).getSQL();
return null; return "Can not extract SQL from exception " + e;
}
private String sqlReport(String header, String jpql, List<String> jSQLs,
List<String> cSQLs) {
StringBuffer tmp = new StringBuffer(header).append("\r\n")
.append("JPQL:["+jpql+"]").append("\r\n");
tmp.append(jSQLs.size() + " target SQL for JPQL").append("\r\n");
for (String s : jSQLs)
tmp.append(s).append("\r\n");
tmp.append(cSQLs.size() + " target SQL for Critera").append("\r\n");
for (String s : cSQLs)
tmp.append(s).append("\r\n");
return tmp.toString();
} }
@Override @Override
@ -327,14 +317,23 @@ public abstract class CriteriaTest extends TestCase {
} }
public class Listener public class SQLAuditor extends AbstractJDBCListener {
extends AbstractJDBCListener { private List<String> sqls = new ArrayList<String>();
@Override @Override
public void beforeExecuteStatement(JDBCEvent event) { public void beforeExecuteStatement(JDBCEvent event) {
if (event.getSQL() != null && sql != null) { if (event.getSQL() != null && sqls != null) {
sql.add(event.getSQL()); System.err.println("Adding " + event.getSQL());
sqls.add(event.getSQL());
}
}
void clear() {
sqls.clear();
}
List<String> getSQLs() {
return new ArrayList<String>(sqls);
} }
} }
} }
}

View File

@ -14,5 +14,4 @@ public class Magazine_ {
public static volatile SingularAttribute<Magazine,Integer> id; public static volatile SingularAttribute<Magazine,Integer> id;
public static volatile SingularAttribute<Magazine,Publisher> idPublisher; public static volatile SingularAttribute<Magazine,Publisher> idPublisher;
public static volatile SingularAttribute<Magazine,String> name; public static volatile SingularAttribute<Magazine,String> name;
public static volatile SingularAttribute<Magazine,Long> serialVersionUID;
} }

View File

@ -13,5 +13,4 @@ public class Publisher_ {
public static volatile SingularAttribute<Publisher,Integer> id; public static volatile SingularAttribute<Publisher,Integer> id;
public static volatile SetAttribute<Publisher,Magazine> magazineCollection; public static volatile SetAttribute<Publisher,Magazine> magazineCollection;
public static volatile SingularAttribute<Publisher,String> name; public static volatile SingularAttribute<Publisher,String> name;
public static volatile SingularAttribute<Publisher,Long> serialVersionUID;
} }

View File

@ -37,21 +37,21 @@ public class TestJoinCondition extends CriteriaTest {
CriteriaQuery<?> cq = cb.createQuery(); CriteriaQuery<?> cq = cb.createQuery();
Root<C> c = cq.from(C.class); Root<C> c = cq.from(C.class);
CollectionJoin<C,D> d = c.join(C_.coll); CollectionJoin<C,D> d = c.join(C_.coll);
assertSame(Collection.class, d.getJavaType()); assertSame(D.class, d.getJavaType());
} }
public void testSetJoinModel() { public void testSetJoinModel() {
CriteriaQuery<?> cq = cb.createQuery(); CriteriaQuery<?> cq = cb.createQuery();
Root<C> c = cq.from(C.class); Root<C> c = cq.from(C.class);
SetJoin<C,D> d = c.join(C_.set); SetJoin<C,D> d = c.join(C_.set);
assertSame(Set.class, d.getJavaType()); assertSame(D.class, d.getJavaType());
} }
public void testListJoinModel() { public void testListJoinModel() {
CriteriaQuery<?> cq = cb.createQuery(); CriteriaQuery<?> cq = cb.createQuery();
Root<C> c = cq.from(C.class); Root<C> c = cq.from(C.class);
ListJoin<C,D> d = c.join(C_.list); ListJoin<C,D> d = c.join(C_.list);
assertSame(List.class, d.getJavaType()); assertSame(D.class, d.getJavaType());
} }
public void testInnerJoinSingleAttributeWithoutCondition() { public void testInnerJoinSingleAttributeWithoutCondition() {

View File

@ -22,11 +22,14 @@ import java.math.BigDecimal;
import java.util.List; import java.util.List;
import javax.persistence.Parameter; import javax.persistence.Parameter;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join; import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType; import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.ListJoin; import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.MapJoin; import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import javax.persistence.criteria.SetJoin; import javax.persistence.criteria.SetJoin;
import javax.persistence.criteria.Subquery; import javax.persistence.criteria.Subquery;
@ -139,7 +142,6 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@AllowFailure(message="FetchJoin not implemented")
public void testFetchJoins() { public void testFetchJoins() {
String jpql = "SELECT d FROM Department d LEFT JOIN FETCH d.employees " String jpql = "SELECT d FROM Department d LEFT JOIN FETCH d.employees "
+ "WHERE d.deptNo = 1"; + "WHERE d.deptNo = 1";
@ -158,30 +160,28 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
+ "JOIN e.contactInfo.phones p " + "JOIN e.contactInfo.phones p "
+ "WHERE e.contactInfo.address.zipCode = '95054'"; + "WHERE e.contactInfo.address.zipCode = '95054'";
CriteriaQuery q = cb.createQuery();
Root<Employee> emp = q.from(Employee.class); CriteriaQuery<String> q = cb.createQuery(String.class);
Join<Contact, Phone> phone = emp.join( Root<Employee> e = q.from(Employee.class);
employee_.getSingularAttribute("contactInfo", Contact.class)).join( Join<Contact, Phone> p = e.join(employee_.getSingularAttribute("contactInfo", Contact.class))
contact_.getList("phones", Phone.class)); .join(contact_.getList("phones", Phone.class));
q.where(cb.equal(emp.get( q.where(cb.equal(e.get(employee_.getSingularAttribute("contactInfo", Contact.class))
employee_.getSingularAttribute("contactInfo", Contact.class)).get( .get(contact_.getSingularAttribute("address", Address.class))
contact_.getSingularAttribute("address", Address.class)).get( .get(address_.getSingularAttribute("zipCode", String.class)),
address_.getSingularAttribute("zipCode", String.class)), "95054")); "95054"));
q.select(phone.get(phone_.getSingularAttribute("vendor", String.class))); q.select(p.get(phone_.getSingularAttribute("vendor", String.class)));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
public void testKeyPathNavigation() { public void testKeyPathNavigation() {
String jpql = "SELECT i.name, p FROM Item i JOIN i.photos p " String jpql = "SELECT i.name, p FROM Item i JOIN i.photos p WHERE KEY(p) LIKE '%egret%'";
+ "WHERE KEY(p) LIKE '%egret%'";
CriteriaQuery q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Item> item = q.from(Item.class); Root<Item> i = q.from(Item.class);
MapJoin<Item, String, Photo> photo = item.join( MapJoin<Item, String, Photo> p = i.join(item_.getMap("photos", String.class, Photo.class));
item_.getMap("photos", String.class, Photo.class)); q.multiselect(i.get(item_.getSingularAttribute("name", String.class)), p)
q.multiselect(item.get(item_.getSingularAttribute("name", String.class)), photo) .where(cb.like(p.key(), "%egret%"));
.where(cb.like(photo.key(), "%egret%"));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -191,23 +191,22 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
+ "WHERE c.customer.accountNum = 321987 AND INDEX(t) BETWEEN 0 " + "WHERE c.customer.accountNum = 321987 AND INDEX(t) BETWEEN 0 "
+ "AND 9"; + "AND 9";
CriteriaQuery cq = cb.createQuery(); CriteriaQuery<TransactionHistory> cq = cb.createQuery(TransactionHistory.class);
Root<CreditCard> c = cq.from(CreditCard.class); Root<CreditCard> c = cq.from(CreditCard.class);
ListJoin<CreditCard, TransactionHistory> t = c.join(creditCard_ ListJoin<CreditCard, TransactionHistory> t = c.join(creditCard_.getList("transactionHistory",
.getList("transactionHistory", TransactionHistory.class)); TransactionHistory.class));
cq.select(t).where( Predicate p1 = cb.equal(
cb.equal(c.get( c.get(creditCard_.getSingularAttribute("customer", Customer.class))
creditCard_.getSingularAttribute("customer", Customer.class)) .get(customer_.getSingularAttribute("accountNum", long.class)), 321987);
.get(customer_.getSingularAttribute("accountNum", Long.class)), Predicate p2 = cb.between(t.index(), 0, 9);
321987), cb.between(t.index(), 0, 9)); cq.select(t).where(p1,p2);
assertEquivalence(cq, jpql); assertEquivalence(cq, jpql);
} }
@AllowFailure(message="as() not implemented")
public void testIsEmptyExpressionOnJoin() { public void testIsEmptyExpressionOnJoin() {
String jpql = "SELECT o FROM Order o WHERE o.lineItems IS EMPTY"; String jpql = "SELECT o FROM Order o WHERE o.lineItems IS EMPTY";
CriteriaQuery q = cb.createQuery(); CriteriaQuery<Order> q = cb.createQuery(Order.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
ListJoin<Order,LineItem> lineItems = ListJoin<Order,LineItem> lineItems =
o.join(order_.getList("lineItems", LineItem.class)); o.join(order_.getList("lineItems", LineItem.class));
@ -221,19 +220,17 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
+ "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a " + "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a "
+ "WHERE a.state = 'CA' AND a.county = 'Santa Clara'"; + "WHERE a.state = 'CA' AND a.county = 'Santa Clara'";
CriteriaQuery q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Customer> cust = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> order = cust.join(customer_.getSet("orders", Join<Customer, Order> o = c.join(customer_.getSet("orders", Order.class));
Order.class)); Join<Customer, Address> a = c.join(customer_.getSingularAttribute("address", Address.class));
Join<Customer, Address> address = cust.join(customer_.getSingularAttribute( Expression<Double> taxedCost = cb.prod(o.get(order_.getSingularAttribute("totalCost", Double.class)), 1.08);
"address", Address.class)); taxedCost.setAlias("taxedCost");
q.where(cb.equal(address.get(address_.getSingularAttribute("state", q.where(cb.equal(a.get(address_.getSingularAttribute("state", String.class)), "CA"),
String.class)), "CA"), cb.equal(address.get(address_ cb.equal(a.get(address_.getSingularAttribute("county", String.class)), "Santa Clara"));
.getSingularAttribute("county", String.class)), "Santa Clara")); q.multiselect(o.get(order_.getSingularAttribute("quantity", Integer.class)),
q.multiselect(order.get(order_.getSingularAttribute("quantity", Integer.class)), taxedCost,
cb.prod(order.get(order_ a.get(address_.getSingularAttribute("zipCode", String.class)));
.getSingularAttribute("totalCost", Double.class)), 1.08),
address.get(address_.getSingularAttribute("zipCode", String.class)));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -251,15 +248,12 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
String jpql = "SELECT w.name FROM Course c JOIN c.studentWaitList w " String jpql = "SELECT w.name FROM Course c JOIN c.studentWaitList w "
+ "WHERE c.name = 'Calculus' AND INDEX(w) = 0"; + "WHERE c.name = 'Calculus' AND INDEX(w) = 0";
CriteriaQuery q = cb.createQuery(); CriteriaQuery<String> q = cb.createQuery(String.class);
Root<Course> course = q.from(Course.class); Root<Course> course = q.from(Course.class);
ListJoin<Course, Student> w = course.join(course_.getList( ListJoin<Course, Student> w = course.join(course_.getList("studentWaitList", Student.class));
"studentWaitList", Student.class)); q.where(cb.equal(course.get(course_.getSingularAttribute("name", String.class)), "Calculus"),
q.where( cb.equal(w.index(), 0))
cb.equal( .select(w.get(student_.getSingularAttribute("name", String.class)));
course.get(course_.getSingularAttribute("name", String.class)),
"Calculus"), cb.equal(w.index(), 0)).select(
w.get(student_.getSingularAttribute("name", String.class)));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -274,10 +268,8 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
LineItem.class)); LineItem.class));
Join<Order, Customer> c = o.join(order_.getSingularAttribute("customer", Join<Order, Customer> c = o.join(order_.getSingularAttribute("customer",
Customer.class)); Customer.class));
q.where(cb q.where(cb.equal(c.get(customer_.getSingularAttribute("lastName", String.class)), "Smith"),
.equal(c.get(customer_.getSingularAttribute("lastName", String.class)), cb.equal(c.get(customer_.getSingularAttribute("firstName", String.class)), "John"));
"Smith"), cb.equal(c.get(customer_.getSingularAttribute(
"firstName", String.class)), "John"));
q.select(cb.sum(i.get(lineItem_.getSingularAttribute("price", Double.class)))); q.select(cb.sum(i.get(lineItem_.getSingularAttribute("price", Double.class))));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
@ -312,18 +304,13 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
employee_.getSingularAttribute("department", Department.class)) employee_.getSingularAttribute("department", Department.class))
.get(department_.getSingularAttribute("name", String.class)), .get(department_.getSingularAttribute("name", String.class)),
"Engineering")); "Engineering"));
q.multiselect(e.get(employee_.getSingularAttribute("name", String.class)), cb q.multiselect(e.get(employee_.getSingularAttribute("name", String.class)),
.selectCase().when( cb.selectCase().when(
cb.equal(e.get(employee_.getSingularAttribute("rating", cb.equal(e.get(employee_.getSingularAttribute("rating", Integer.class)), 1),
Integer.class)), 1), cb.prod(e.get(employee_.getSingularAttribute("salary", Long.class)), 1.1)).when(
cb.prod(e.get(employee_.getSingularAttribute("salary", cb.equal(e.get(employee_.getSingularAttribute("rating", Integer.class)), 2),
Long.class)), 1.1)).when( cb.prod(e.get(employee_.getSingularAttribute("salary", Long.class)), 1.2)).otherwise(
cb.equal(e.get(employee_.getSingularAttribute("rating", cb.prod(e.get(employee_.getSingularAttribute("salary", Long.class)), 1.01)));
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); assertEquivalence(q, jpql);
} }
@ -350,22 +337,21 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
assertEquivalence(q, jpql, new String[] { "stat" }, new Object[] { 1 }); assertEquivalence(q, jpql, new String[] { "stat" }, new Object[] { 1 });
} }
@AllowFailure(message="Generates invalid SQL")
public void testKeyExpressionInSelectList() { public void testKeyExpressionInSelectList() {
String jpql = "SELECT v.location.street, KEY(i).title, VALUE(i) FROM " String jpql = "SELECT v.location.street, KEY(i).title, VALUE(i) "
+ "VideoStore v JOIN v.videoInventory i " + "FROM VideoStore v JOIN v.videoInventory i "
+ "WHERE v.location.zipCode = " + "'94301' AND VALUE(i) > 0"; + "WHERE v.location.zipCode = '94301' AND VALUE(i) > 0";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<?> q = cb.createQuery();
Root<VideoStore> v = q.from(VideoStore.class); Root<VideoStore> v = q.from(VideoStore.class);
MapJoin<VideoStore, Movie, Integer> inv = v.join(videoStore_.getMap( MapJoin<VideoStore, Movie, Integer> i = v.join(videoStore_.getMap("videoInventory", Movie.class,Integer.class));
"videoInventory", Movie.class, Integer.class)); q.where(cb.equal(v.get(videoStore_.getSingularAttribute("location", Address.class))
q.where(cb.equal(v.get( .get(address_.getSingularAttribute("zipCode", String.class)), "94301"),
videoStore_.getSingularAttribute("location", Address.class)).get( cb.gt(i.value(), 0));
address_.getSingularAttribute("zipCode", String.class)), "94301"), cb
.gt(inv.value(), 0));
q.multiselect(v.get(videoStore_.getSingularAttribute("location", Address.class)) q.multiselect(v.get(videoStore_.getSingularAttribute("location", Address.class))
.get(address_.getSingularAttribute("street", String.class)), inv.key() .get(address_.getSingularAttribute("street", String.class)),
.get(movie_.getSingularAttribute("title", String.class)), inv.value()); i.key().get(movie_.getSingularAttribute("title", String.class)),
i.value());
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -474,7 +460,6 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@AllowFailure(message="Root of the subquery._delegate not set")
public void testCorrelatedSubqueryWithAllClause() { public void testCorrelatedSubqueryWithAllClause() {
String jpql = "SELECT o FROM Order o JOIN o.customer c " String jpql = "SELECT o FROM Order o JOIN o.customer c "
+ "WHERE 10000 < ALL (SELECT a.balance FROM c.accounts a)"; + "WHERE 10000 < ALL (SELECT a.balance FROM c.accounts a)";
@ -557,30 +542,25 @@ public class TestMetaModelTypesafeCriteria extends CriteriaTest {
} }
public void testOrderingWithNumericalExpressionInSelection() { public void testOrderingWithNumericalExpressionInSelection() {
String jpql = "SELECT o.quantity, o.totalCost * 1.08 AS taxedCost, " String jpql = "SELECT o.quantity, o.totalCost * 1.08 AS taxedCost, a.zipCode "
+ "a.zipCode "
+ "FROM Customer c JOIN c.orders o JOIN c.address a " + "FROM Customer c JOIN c.orders o JOIN c.address a "
+ "WHERE a.state = 'CA' AND a.county = 'Santa Clara' " + "WHERE a.state = 'CA' AND a.county = 'Santa Clara' "
+ "ORDER BY o.quantity, taxedCost, a.zipCode"; + "ORDER BY o.quantity, taxedCost, a.zipCode";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<?> q = cb.createQuery();
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(customer_.getSet("orders", Join<Customer, Order> o = c.join(customer_.getSet("orders", Order.class));
Order.class)); Join<Customer, Address> a = c.join(customer_.getSingularAttribute("address", Address.class));
Join<Customer, Address> a = c.join(customer_.getSingularAttribute("address", Expression<Double> taxedCost = cb.prod(o.get(order_.getSingularAttribute("totalCost", Double.class)), 1.08);
Address.class)); taxedCost.setAlias("taxedCost");
q.where(cb.equal(a.get(address_.getSingularAttribute("state", String.class)), q.where(cb.equal(a.get(address_.getSingularAttribute("state", String.class)), "CA"),
"CA"), cb.equal(a.get(address_.getSingularAttribute("county", cb.equal(a.get(address_.getSingularAttribute("county", String.class)), "Santa Clara"));
String.class)), "Santa Clara")); q.orderBy(cb.asc(o.get(order_.getSingularAttribute("quantity", Integer.class))),
q.orderBy( cb.asc(taxedCost),
cb.asc(o.get(order_.getSingularAttribute("quantity", Integer.class))), cb.asc(a.get(address_.getSingularAttribute("zipCode", String.class))));
cb.asc(cb.prod(o.get(order_.getSingularAttribute("totalCost", q.multiselect(o.get(order_.getSingularAttribute("quantity", Integer.class)),
Double.class)), 1.08)), cb.asc(a.get(address_ taxedCost,
.getSingularAttribute("zipCode", String.class)))); a.get(address_.getSingularAttribute("zipCode", String.class)));
q.multiselect(o.get(order_.getSingularAttribute("quantity", Integer.class)), cb
.prod(o.get(order_.getSingularAttribute("totalCost", Double.class)),
1.08), a.get(address_.getSingularAttribute("zipCode",
String.class)));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
} }

View File

@ -2,6 +2,7 @@ package org.apache.openjpa.persistence.criteria;
import java.sql.Timestamp; import java.sql.Timestamp;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression; import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join; import javax.persistence.criteria.Join;
@ -20,7 +21,7 @@ public class TestSubqueries extends CriteriaTest {
String query = "SELECT DISTINCT o.name FROM CompUser o WHERE EXISTS" String query = "SELECT DISTINCT o.name FROM CompUser o WHERE EXISTS"
+ " (SELECT c FROM Address c WHERE c = o.address )"; + " (SELECT c FROM Address c WHERE c = o.address )";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<String> q = cb.createQuery(String.class);
Root<CompUser> o = q.from(CompUser.class); Root<CompUser> o = q.from(CompUser.class);
Subquery<Address> sq = q.subquery(Address.class); Subquery<Address> sq = q.subquery(Address.class);
sq.correlate(o); sq.correlate(o);
@ -28,7 +29,7 @@ public class TestSubqueries extends CriteriaTest {
sq.select(c); sq.select(c);
sq.where(cb.equal(c, o.get(CompUser_.address))); sq.where(cb.equal(c, o.get(CompUser_.address)));
q.where(cb.exists(sq)); q.where(cb.exists(sq));
// q.select(o.get(CompUser_.name)).distinct(true); q.select(o.get(CompUser_.name)).distinct(true);
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -38,7 +39,7 @@ public class TestSubqueries extends CriteriaTest {
+ " (SELECT s FROM CompUser s WHERE s.address.country = " + " (SELECT s FROM CompUser s WHERE s.address.country = "
+ "o.address.country)"; + "o.address.country)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<String> q = cb.createQuery(String.class);
Root<CompUser> o = q.from(CompUser.class); Root<CompUser> o = q.from(CompUser.class);
Subquery<CompUser> sq = q.subquery(CompUser.class); Subquery<CompUser> sq = q.subquery(CompUser.class);
sq.correlate(o); sq.correlate(o);
@ -47,7 +48,7 @@ public class TestSubqueries extends CriteriaTest {
sq.where(cb.equal(s.get(CompUser_.address).get(Address_.country), o sq.where(cb.equal(s.get(CompUser_.address).get(Address_.country), o
.get(CompUser_.address).get(Address_.country))); .get(CompUser_.address).get(Address_.country)));
q.where(cb.exists(sq).negate()); q.where(cb.exists(sq).negate());
// q.select(o.get(CompUser_.name)).distinct(true); q.select(o.get(CompUser_.name)).distinct(true);
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -58,9 +59,9 @@ public class TestSubqueries extends CriteriaTest {
+ " ANY (SELECT s.computerName " + " ANY (SELECT s.computerName "
+ " FROM CompUser s WHERE s.address.country IS NOT NULL)"; + " FROM CompUser s WHERE s.address.country IS NOT NULL)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<String> q = cb.createQuery(String.class);
Root<CompUser> o = q.from(CompUser.class); Root<CompUser> o = q.from(CompUser.class);
// q.select(o.get(CompUser_.name)); q.select(o.get(CompUser_.name));
Subquery<String> sq = q.subquery(String.class); Subquery<String> sq = q.subquery(String.class);
Root<CompUser> s = sq.from(CompUser.class); Root<CompUser> s = sq.from(CompUser.class);
sq.select(s.get(CompUser_.computerName)); sq.select(s.get(CompUser_.computerName));
@ -77,9 +78,9 @@ public class TestSubqueries extends CriteriaTest {
+ " (select distinct o.id from LineItem i, Order o" + " (select distinct o.id from LineItem i, Order o"
+ " where i.quantity > 10 and o.count > 1000 and i.id = o.id)"; + " where i.quantity > 10 and o.count > 1000 and i.id = o.id)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o1 = q.from(Order.class); Root<Order> o1 = q.from(Order.class);
// q.select(o1.get(Order_.id)); q.select(o1.get(Order_.id));
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Root<LineItem> i = sq.from(LineItem.class); Root<LineItem> i = sq.from(LineItem.class);
@ -98,9 +99,10 @@ public class TestSubqueries extends CriteriaTest {
String query = "select o.id from Order o where o.customer.balanceOwed =" String query = "select o.id from Order o where o.customer.balanceOwed ="
+ " (select max(o2.customer.balanceOwed) from Order o2" + " (select max(o2.customer.balanceOwed) from Order o2"
+ " where o.customer.id = o2.customer.id)"; + " where o.customer.id = o2.customer.id)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Root<Order> o2 = sq.from(Order.class); Root<Order> o2 = sq.from(Order.class);
sq.where(cb.equal(o.get(Order_.customer).get(Customer_.id), o2.get( sq.where(cb.equal(o.get(Order_.customer).get(Customer_.id), o2.get(
@ -116,9 +118,10 @@ public class TestSubqueries extends CriteriaTest {
String query = "select o from Order o where o.customer.balanceOwed =" String query = "select o from Order o where o.customer.balanceOwed ="
+ " (select max(o2.customer.balanceOwed) from Order o2" + " (select max(o2.customer.balanceOwed) from Order o2"
+ " where o.customer.id = o2.customer.id)"; + " where o.customer.id = o2.customer.id)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Order> q = cb.createQuery(Order.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o); q.select(o);
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Root<Order> o2 = sq.from(Order.class); Root<Order> o2 = sq.from(Order.class);
sq.where(cb.equal(o.get(Order_.customer).get(Customer_.id), o2.get( sq.where(cb.equal(o.get(Order_.customer).get(Customer_.id), o2.get(
@ -133,9 +136,10 @@ public class TestSubqueries extends CriteriaTest {
public void testSubquery04() { public void testSubquery04() {
String query = "select o.id from Order o where o.quantity >" String query = "select o.id from Order o where o.quantity >"
+ " (select count(i) from o.lineItems i)"; + " (select count(i) from o.lineItems i)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Long> sq = q.subquery(Long.class); Subquery<Long> sq = q.subquery(Long.class);
Root<Order> osq = sq.correlate(o); Root<Order> osq = sq.correlate(o);
Join<Order, LineItem> i = osq.join(Order_.lineItems); Join<Order, LineItem> i = osq.join(Order_.lineItems);
@ -146,9 +150,10 @@ public class TestSubqueries extends CriteriaTest {
public void testSubquery05() { public void testSubquery05() {
String query = "select o.id from Order o where o.quantity >" String query = "select o.id from Order o where o.quantity >"
+ " (select count(o.quantity) from Order o)"; + " (select count(o.quantity) from Order o)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Long> sq = q.subquery(Long.class); Subquery<Long> sq = q.subquery(Long.class);
Root<Order> o2 = sq.from(Order.class); Root<Order> o2 = sq.from(Order.class);
q.where(cb.gt(o.get(Order_.quantity), sq.select(cb.count(o2 q.where(cb.gt(o.get(Order_.quantity), sq.select(cb.count(o2
@ -161,9 +166,10 @@ public class TestSubqueries extends CriteriaTest {
public void testSubquery06() { public void testSubquery06() {
String query = "select o.id from Order o where o.quantity >" String query = "select o.id from Order o where o.quantity >"
+ " (select count(o.id) from Order o)"; + " (select count(o.id) from Order o)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Long> sq = q.subquery(Long.class); Subquery<Long> sq = q.subquery(Long.class);
Root<Order> o2 = sq.from(Order.class); Root<Order> o2 = sq.from(Order.class);
q.where(cb.gt(o.get(Order_.quantity), sq.select(cb.count(o2 q.where(cb.gt(o.get(Order_.quantity), sq.select(cb.count(o2
@ -176,9 +182,10 @@ public class TestSubqueries extends CriteriaTest {
public void testSubquery07() { public void testSubquery07() {
String query = "select o.id from Order o where o.quantity >" String query = "select o.id from Order o where o.quantity >"
+ " (select avg(o.quantity) from Order o)"; + " (select avg(o.quantity) from Order o)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Double> sq = q.subquery(Double.class); Subquery<Double> sq = q.subquery(Double.class);
Root<Order> o2 = sq.from(Order.class); Root<Order> o2 = sq.from(Order.class);
q.where(cb.gt(o.get(Order_.quantity), sq.select(cb.avg(o2 q.where(cb.gt(o.get(Order_.quantity), sq.select(cb.avg(o2
@ -190,12 +197,12 @@ public class TestSubqueries extends CriteriaTest {
@AllowFailure(message="JPQL generates invalid SQL") @AllowFailure(message="JPQL generates invalid SQL")
public void testSubquery08() { public void testSubquery08() {
String query = "select c.name from Customer c " String query = "select c.name from Customer c "
+ "where exists (select o from c.orders o where o.id = 1) " + "where exists(select o from c.orders o where o.id = 1) "
+ "or exists (select o from c.orders o where o.id = 2)"; + "or exists(select o from c.orders o where o.id = 2)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<String> q = cb.createQuery(String.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
// q.select(c.get(Customer_.name)); q.select(c.get(Customer_.name));
Subquery<Order> sq1 = q.subquery(Order.class); Subquery<Order> sq1 = q.subquery(Order.class);
Root<Customer> c1 = sq1.correlate(c); Root<Customer> c1 = sq1.correlate(c);
SetJoin<Customer, Order> o1 = c1.join(Customer_.orders); SetJoin<Customer, Order> o1 = c1.join(Customer_.orders);
@ -217,9 +224,10 @@ public class TestSubqueries extends CriteriaTest {
+ "where o.quantity between " + "where o.quantity between "
+ "(select max(o.quantity) from Order o) and " + "(select max(o.quantity) from Order o) and "
+ "(select avg(o.quantity) from Order o) "; + "(select avg(o.quantity) from Order o) ";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<String> q = cb.createQuery(String.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
// q.select(c.get(Customer_.name)); q.select(c.get(Customer_.name));
Subquery<Integer> sq1 = q.subquery(Integer.class); Subquery<Integer> sq1 = q.subquery(Integer.class);
Root<Order> o1 = sq1.from(Order.class); Root<Order> o1 = sq1.from(Order.class);
@ -230,9 +238,7 @@ public class TestSubqueries extends CriteriaTest {
sq2.select(cb.avg(o2.get(Order_.quantity))); sq2.select(cb.avg(o2.get(Order_.quantity)));
SetJoin<Customer, Order> o = c.join(Customer_.orders); SetJoin<Customer, Order> o = c.join(Customer_.orders);
// not sure how to do call between of integer(quantity) q.where(cb.between(o.get(Order_.quantity), sq1, sq2.as(Integer.class)));
// between integer (max quantity) and double (avg quantity)
// q.where(cb.between(o.get(Order_.quantity), sq1, sq2));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -243,9 +249,10 @@ public class TestSubqueries extends CriteriaTest {
+ " (select sum(o2.quantity) from Customer c, " + " (select sum(o2.quantity) from Customer c, "
+ "in(c.orders) o2) "; + "in(c.orders) o2) ";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Root<Customer> c = sq.from(Customer.class); Root<Customer> c = sq.from(Customer.class);
@ -263,9 +270,10 @@ public class TestSubqueries extends CriteriaTest {
+ " (select avg(o2.quantity) from Customer c, in(c.orders) o2)" + " (select avg(o2.quantity) from Customer c, in(c.orders) o2)"
+ " and (select min(o2.quantity) from Customer c, in(c.orders)" + " and (select min(o2.quantity) from Customer c, in(c.orders)"
+ " o2)"; + " o2)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Double> sq1 = q.subquery(Double.class); Subquery<Double> sq1 = q.subquery(Double.class);
Root<Customer> c = sq1.from(Customer.class); Root<Customer> c = sq1.from(Customer.class);
@ -277,21 +285,20 @@ public class TestSubqueries extends CriteriaTest {
SetJoin<Customer, Order> o3 = c2.join(Customer_.orders); SetJoin<Customer, Order> o3 = c2.join(Customer_.orders);
sq2.select(cb.min(o3.get(Order_.quantity))); sq2.select(cb.min(o3.get(Order_.quantity)));
// do not know how to call between for double and integer q.where(cb.between(o2.get(Order_.quantity), sq1.as(Integer.class), sq2));
// q.where(cb.between(o2.get(Order_.quantity), sq1, sq2));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
public void testSubquery12() { public void testSubquery12() {
String query = String query = "select o.id from Customer c, in(c.orders)o "
"select o.id from Customer c, in(c.orders)o "
+ "where o.quantity > (select sum(o2.quantity)" + "where o.quantity > (select sum(o2.quantity)"
+ " from c.orders o2)"; + " from c.orders o2)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
SetJoin<Customer, Order> o = c.join(Customer_.orders); SetJoin<Customer, Order> o = c.join(Customer_.orders);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Root<Customer> sqc = sq.correlate(c); Root<Customer> sqc = sq.correlate(c);
@ -307,10 +314,11 @@ public class TestSubqueries extends CriteriaTest {
String query = "select o1.id, c.name from Order o1, Customer c" String query = "select o1.id, c.name from Order o1, Customer c"
+ " where o1.quantity = " + " where o1.quantity = "
+ " any(select o2.quantity from in(c.orders) o2)"; + " any(select o2.quantity from in(c.orders) o2)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Order> o1 = q.from(Order.class); Root<Order> o1 = q.from(Order.class);
Join<Order, Customer> c = o1.join(Order_.customer); Join<Order, Customer> c = o1.join(Order_.customer);
// q.select(o1.get(Order_.id), c.get(Customer_.name)); q.multiselect(o1.get(Order_.id), c.get(Customer_.name));
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Join<Order, Customer> sqc = sq.correlate(c); Join<Order, Customer> sqc = sq.correlate(c);
@ -331,11 +339,11 @@ public class TestSubqueries extends CriteriaTest {
+ "(SELECT MAX(m3.id) FROM Magazine m3 " + "(SELECT MAX(m3.id) FROM Magazine m3 "
+ "WHERE m3.idPublisher.id = p.id)) "; + "WHERE m3.idPublisher.id = p.id)) ";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Publisher> p = q.from(Publisher.class); Root<Publisher> p = q.from(Publisher.class);
Join<Publisher, Magazine> m = p.join(Publisher_.magazineCollection, Join<Publisher, Magazine> m = p.join(Publisher_.magazineCollection,
JoinType.LEFT); JoinType.LEFT);
// q.select(p, m); q.multiselect(p, m);
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Root<Magazine> m2 = sq.from(Magazine.class); Root<Magazine> m2 = sq.from(Magazine.class);
@ -376,9 +384,10 @@ public class TestSubqueries extends CriteriaTest {
+ " WHEN o2.quantity = 10 THEN false " + " WHEN o2.quantity = 10 THEN false "
+ " ELSE false END from Order o2" + " ELSE false END from Order o2"
+ " where o.customer.id = o2.customer.id)"; + " where o.customer.id = o2.customer.id)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Boolean> sq = q.subquery(Boolean.class); Subquery<Boolean> sq = q.subquery(Boolean.class);
Root<Order> o2 = sq.from(Order.class); Root<Order> o2 = sq.from(Order.class);
@ -402,9 +411,10 @@ public class TestSubqueries extends CriteriaTest {
+ " (select o.quantity*2 from LineItem i, Order o" + " (select o.quantity*2 from LineItem i, Order o"
+ " where i.quantity > 10 and o.quantity > 1000 and i.id = " + + " where i.quantity > 10 and o.quantity > 1000 and i.id = " +
"o.id)"; "o.id)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o1 = q.from(Order.class); Root<Order> o1 = q.from(Order.class);
// q.select(o1.get(Order_.id)); q.select(o1.get(Order_.id));
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Root<LineItem> i = sq.from(LineItem.class); Root<LineItem> i = sq.from(LineItem.class);
@ -424,9 +434,10 @@ public class TestSubqueries extends CriteriaTest {
String query = "select o.id from Order o where o.customer.name =" String query = "select o.id from Order o where o.customer.name ="
+ " (select substring(o2.customer.name, 3) from Order o2" + " (select substring(o2.customer.name, 3) from Order o2"
+ " where o.customer.id = o2.customer.id)"; + " where o.customer.id = o2.customer.id)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.customer).get(Customer_.name)); q.select(o.get(Order_.id));
Subquery<String> sq = q.subquery(String.class); Subquery<String> sq = q.subquery(String.class);
Root<Order> o2 = sq.from(Order.class); Root<Order> o2 = sq.from(Order.class);
@ -444,9 +455,10 @@ public class TestSubqueries extends CriteriaTest {
public void testSubquery18() { public void testSubquery18() {
String query = "select o.id from Order o where o.orderTs >" String query = "select o.id from Order o where o.orderTs >"
+ " (select CURRENT_TIMESTAMP from o.lineItems i)"; + " (select CURRENT_TIMESTAMP from o.lineItems i)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o.get(Order_.id)); q.select(o.get(Order_.id));
Subquery<Timestamp> sq = q.subquery(Timestamp.class); Subquery<Timestamp> sq = q.subquery(Timestamp.class);
Root<Order> o2 = sq.correlate(o); Root<Order> o2 = sq.correlate(o);

View File

@ -37,11 +37,16 @@
package org.apache.openjpa.persistence.criteria; package org.apache.openjpa.persistence.criteria;
import javax.persistence.Parameter; import javax.persistence.Parameter;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression; import javax.persistence.criteria.Expression;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import javax.persistence.criteria.Selection;
import javax.persistence.criteria.Subquery; import javax.persistence.criteria.Subquery;
import org.apache.openjpa.persistence.inheritance.entity.ComputerUser;
/** /**
* Tests type-strict version of Criteria API. The test scenarios are adapted * Tests type-strict version of Criteria API. The test scenarios are adapted
* from TestEJBQLCondExpression in * from TestEJBQLCondExpression in
@ -86,26 +91,24 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
} }
public void testInExpr() { public void testInExpr() {
String jpql = "SELECT o.name FROM CompUser o " String jpql = "SELECT o.name FROM CompUser o WHERE o.age IN (29, 40, 10)";
+ "WHERE o.age IN (29, 40, 10)";
CriteriaQuery<?> cq = cb.createQuery(); CriteriaQuery<String> cq = cb.createQuery(String.class);
Root<CompUser> o = cq.from(CompUser.class); Root<CompUser> o = cq.from(CompUser.class);
cq.where(cb.in(o.get(CompUser_.age)).value(29).value(40).value(10)); cq.where(cb.in(o.get(CompUser_.age)).value(29).value(40).value(10));
// cq.select(o.get(CompUser_.name)); cq.select(o.get(CompUser_.name));
assertEquivalence(cq, jpql); assertEquivalence(cq, jpql);
} }
public void testNotIn() { public void testNotIn() {
String jpql = "SELECT o.name FROM CompUser o " String jpql = "SELECT o.name FROM CompUser o WHERE o.age NOT IN (29, 40, 10)";
+ "WHERE o.age NOT IN (29, 40, 10)";
CriteriaQuery<?> cq = cb.createQuery(); CriteriaQuery<String> cq = cb.createQuery(String.class);
Root<CompUser> o = cq.from(CompUser.class); Root<CompUser> o = cq.from(CompUser.class);
cq.where(cb.in(o.get(CompUser_.age)).value(29).value(40).value(10) cq.where(cb.in(o.get(CompUser_.age)).value(29).value(40).value(10)
.negate()); .negate());
// cq.select(o.get(CompUser_.name)); cq.select(o.get(CompUser_.name));
assertEquivalence(cq, jpql); assertEquivalence(cq, jpql);
} }
@ -114,14 +117,14 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
String jpql = "SELECT o.computerName FROM CompUser o " String jpql = "SELECT o.computerName FROM CompUser o "
+ "WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC')"; + "WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC')";
CriteriaQuery<?> cq = cb.createQuery(); CriteriaQuery<String> cq = cb.createQuery(String.class);
Root<CompUser> o = cq.from(CompUser.class); Root<CompUser> o = cq.from(CompUser.class);
cq.where(cb.and( cq.where(cb.and(
cb.like(o.get(CompUser_.name),"Sha%"), cb.like(o.get(CompUser_.name),"Sha%"),
cb.in(o.get(CompUser_.computerName)).value("PC").negate() cb.in(o.get(CompUser_.computerName)).value("PC").negate()
)); ));
// cq.select(o.get(CompUser_.computerName)); cq.select(o.get(CompUser_.computerName));
assertEquivalence(cq, jpql); assertEquivalence(cq, jpql);
} }
@ -153,22 +156,20 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
} }
public void testLikeWithEscapeCharacter() { public void testLikeWithEscapeCharacter() {
String query = "SELECT o.name FROM CompUser o " String query = "SELECT o.name FROM CompUser o WHERE o.name LIKE :name ESCAPE '|'";
+ "WHERE o.name LIKE :name ESCAPE '|'";
CriteriaQuery<?> cq = cb.createQuery();
Root<CompUser> c = cq.from(CompUser.class);
Parameter<String> param = cb.parameter(String.class, "name");
// cq.where(cb.like(c.get(CompUser_.name), param, '|'));
// cq.select(c.get(CompUser_.name));
assertEquivalence(cq, query, new String[]{"name"}, CriteriaQuery<String> cq = cb.createQuery(String.class);
new Object[] {"%|_%"}); Root<CompUser> c = cq.from(CompUser.class);
ParameterExpression<String> param = cb.parameter(String.class, "name");
cq.where(cb.like(c.get(CompUser_.name), param, '|'));
cq.select(c.get(CompUser_.name));
assertEquivalence(cq, query, new String[]{"name"}, new Object[] {"%|_%"});
} }
public void testNullExpression() { public void testNullExpression() {
String query = String query = "SELECT o.name FROM CompUser o "
"SELECT o.name FROM CompUser o WHERE o.age IS NOT NULL AND " + + "WHERE o.age IS NOT NULL AND o.computerName = 'PC'";
"o.computerName = 'PC' ";
CriteriaQuery<String> cq = cb.createQuery(String.class); CriteriaQuery<String> cq = cb.createQuery(String.class);
Root<CompUser> c = cq.from(CompUser.class); Root<CompUser> c = cq.from(CompUser.class);
@ -195,8 +196,7 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
// do not support isEmpty for array fields // do not support isEmpty for array fields
public void testIsEmptyExprUsingCriteria() { public void testIsEmptyExprUsingCriteria() {
String query = String query = "SELECT o.name FROM CompUser o WHERE o.nicknames IS NOT EMPTY";
"SELECT o.name FROM CompUser o WHERE o.nicknames IS NOT EMPTY";
CriteriaQuery<String> cq = cb.createQuery(String.class); CriteriaQuery<String> cq = cb.createQuery(String.class);
Root<CompUser> o = cq.from(CompUser.class); Root<CompUser> o = cq.from(CompUser.class);
@ -208,17 +208,16 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testConstructorExprUsingCriteria() { public void testConstructorExprUsingCriteria() {
String query = String query = "SELECT NEW org.apache.openjpa.persistence.criteria.MaleUser(" +
"SELECT NEW org.apache.openjpa.persistence.criteria.MaleUser(" +
"c.name, c.computerName, c.address, c.age, c.userid)" + "c.name, c.computerName, c.address, c.age, c.userid)" +
" FROM CompUser c WHERE c.name = 'Seetha'"; " FROM CompUser c WHERE c.name = 'Seetha'";
CriteriaQuery<?> cq = cb.createQuery(); CriteriaQuery<MaleUser> cq = cb.createQuery(MaleUser.class);
Root<CompUser> c = cq.from(CompUser.class); Root<CompUser> c = cq.from(CompUser.class);
cq.where(cb.equal(c.get(CompUser_.name), "Seetha")); cq.where(cb.equal(c.get(CompUser_.name), "Seetha"));
// cq.select(cb.select(MaleUser.class, c.get(CompUser_.name), cq.select(cb.construct(MaleUser.class, c.get(CompUser_.name),
// c.get(CompUser_.computerName), c.get(CompUser_.address), c.get(CompUser_.computerName), c.get(CompUser_.address),
// c.get(CompUser_.age), c.get(CompUser_.userid))); c.get(CompUser_.age), c.get(CompUser_.userid)));
assertEquivalence(cq, query); assertEquivalence(cq, query);
} }
@ -389,11 +388,11 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
} }
public void testArithmFunc2() { public void testArithmFunc2() {
String query = String query = "select SQRT(e.age) From CompUser e WHERE e.name='Seetha'";
"select SQRT(e.age) From CompUser e WHERE e.name='Seetha'";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Double> q = cb.createQuery(Double.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(cb.sqrt(e.get(CompUser_.age))); q.select(cb.sqrt(e.get(CompUser_.age)));
q.where(cb.equal(e.get(CompUser_.name), "Seetha")); q.where(cb.equal(e.get(CompUser_.name), "Seetha"));
assertEquivalence(q, query); assertEquivalence(q, query);
@ -401,50 +400,46 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testArithmFunc3() { public void testArithmFunc3() {
String query = String query = "select MOD(e.age, 4) From CompUser e WHERE e.name='Seetha'";
"select MOD(e.age, 4) From CompUser e WHERE e.name='Seetha'";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(cb.mod(e.get(CompUser_.age), 4)); q.select(cb.mod(e.get(CompUser_.age), 4));
q.where(cb.equal(e.get(CompUser_.name), "Seetha")); q.where(cb.equal(e.get(CompUser_.name), "Seetha"));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
public void testArithmFunc4() { public void testArithmFunc4() {
String query = "SELECT e.name FROM CompUser e WHERE " + String query = "SELECT e.name FROM CompUser e WHERE SIZE(e.nicknames) = 6";
"SIZE(e.nicknames) = 6";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<String> q = cb.createQuery(String.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
//q.where(cb.equal(cb.size(e.get(CompUser_.nicknames)), 6)); q.where(cb.equal(cb.size(e.get(CompUser_.nicknames)), 6));
// q.select(e.get(CompUser_.name)); q.select(e.get(CompUser_.name));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
public void testGroupByHavingClause() { public void testGroupByHavingClause() {
String query = String query = "SELECT c.name FROM CompUser c GROUP BY c.name HAVING c.name LIKE 'S%'";
"SELECT c.name FROM CompUser c GROUP BY c.name HAVING c.name " +
"LIKE 'S%'";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<String> q = cb.createQuery(String.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
q.groupBy(e.get(CompUser_.name)); q.groupBy(e.get(CompUser_.name));
q.having(cb.like(e.get(CompUser_.name), "S%")); q.having(cb.like(e.get(CompUser_.name), "S%"));
// q.select(e.get(CompUser_.name)); q.select(e.get(CompUser_.name));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
public void testOrderByClause() { public void testOrderByClause() {
String query = String query = "SELECT c.name FROM CompUser c WHERE c.name LIKE 'S%' ORDER BY c.name";
"SELECT c.name FROM CompUser c WHERE c.name LIKE 'S%' " +
"ORDER BY c.name";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<String> q = cb.createQuery(String.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
q.where(cb.like(e.get(CompUser_.name), "S%")); q.where(cb.like(e.get(CompUser_.name), "S%"));
// q.select(e.get(CompUser_.name)); q.select(e.get(CompUser_.name));
q.orderBy(cb.asc(e.get(CompUser_.name))); q.orderBy(cb.asc(e.get(CompUser_.name)));
assertEquivalence(q, query); assertEquivalence(q, query);
@ -454,9 +449,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
//To be Tested: AVG, COUNT, MAX, MIN, SUM //To be Tested: AVG, COUNT, MAX, MIN, SUM
String query = "SELECT AVG(e.age) FROM CompUser e"; String query = "SELECT AVG(e.age) FROM CompUser e";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Double> q = cb.createQuery(Double.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(cb.avg(e.get(CompUser_.age))); q.select(cb.avg(e.get(CompUser_.age)));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -464,9 +459,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testCOUNTAggregFunc() { public void testCOUNTAggregFunc() {
String query = "SELECT COUNT(c.name) FROM CompUser c"; String query = "SELECT COUNT(c.name) FROM CompUser c";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Long> q = cb.createQuery(Long.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(cb.count(e.get(CompUser_.name))); q.select(cb.count(e.get(CompUser_.name)));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -474,9 +469,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testMAXAggregFunc() { public void testMAXAggregFunc() {
String query = "SELECT DISTINCT MAX(c.age) FROM CompUser c"; String query = "SELECT DISTINCT MAX(c.age) FROM CompUser c";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(cb.max(e.get(CompUser_.age))).distinct(true); q.select(cb.max(e.get(CompUser_.age))).distinct(true);
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -484,9 +479,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testMINAggregFunc() { public void testMINAggregFunc() {
String query = "SELECT DISTINCT MIN(c.age) FROM CompUser c"; String query = "SELECT DISTINCT MIN(c.age) FROM CompUser c";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(cb.min(e.get(CompUser_.age))).distinct(true); q.select(cb.min(e.get(CompUser_.age))).distinct(true);
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -494,20 +489,19 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testSUMAggregFunc() { public void testSUMAggregFunc() {
String query = "SELECT SUM(c.age) FROM CompUser c"; String query = "SELECT SUM(c.age) FROM CompUser c";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(cb.sum(e.get(CompUser_.age))); q.select(cb.sum(e.get(CompUser_.age)));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
public void testTypeExpression1() { public void testTypeExpression1() {
String jpql = "SELECT e FROM CompUser e where TYPE(e) in (:a, :b) " + String jpql = "SELECT e FROM CompUser e where TYPE(e) in (:a, :b) ORDER By e.name";
"ORDER By e.name";
CriteriaQuery<?> cq = cb.createQuery(); CriteriaQuery<CompUser> cq = cb.createQuery(CompUser.class);
Root<CompUser> e = cq.from(CompUser.class); Root<CompUser> e = cq.from(CompUser.class);
// cq.select(e); cq.select(e);
Parameter<Class> param1 = cb.parameter(Class.class, "a"); Parameter<Class> param1 = cb.parameter(Class.class, "a");
Parameter<Class> param2 = cb.parameter(Class.class, "b"); Parameter<Class> param2 = cb.parameter(Class.class, "b");
cq.where(e.type().in(param1, param2)); cq.where(e.type().in(param1, param2));
@ -520,27 +514,29 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testTypeExpression2() { public void testTypeExpression2() {
String query = "SELECT TYPE(e) FROM CompUser e where TYPE(e) <> :t"; String query = "SELECT TYPE(e) FROM CompUser e where TYPE(e) <> :t";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
Parameter<Class> param1 = cb.parameter(Class.class, "t"); Parameter<Class> param1 = cb.parameter(Class.class, "t");
// q.select(e.type()); Expression<Class<? extends CompUser>> etype = e.type();
// how to specify the following
q.multiselect(e.type());
q.where(cb.equal(e.type(), param1).negate()); q.where(cb.equal(e.type(), param1).negate());
assertEquivalence(q, query, new String[]{"t"}, assertEquivalence(q, query, new String[]{"t"}, new Class[]{MaleUser.class});
new Class[]{MaleUser.class});
} }
// Type literal // Type literal
// this Cartesian problem can not be rewritten to use JOIN // this Cartesian problem can not be rewritten to use JOIN
public void testTypeExpression3() { public void testTypeExpression3() {
String query = "SELECT e, FemaleUser, a FROM Address a, FemaleUser e " String query = "SELECT e, FemaleUser, a FROM Address a, FemaleUser e where e.address IS NOT NULL";
+ " where e.address IS NOT NULL";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Address> a = q.from(Address.class); Root<Address> a = q.from(Address.class);
// Join<Address,FemaleUser> e = a.join(Address_.user); Root<FemaleUser> e = q.from(FemaleUser.class);
// q.select(cb.literal(FemaleUser.class), e.get(CompUser_.address)); q.multiselect(e, cb.literal(FemaleUser.class), e.get(CompUser_.address));
// q.where(cb.equal(e.type(), null).negate()); q.where(e.get(FemaleUser_.address).isNotNull());
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -548,9 +544,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testTypeExpression4() { public void testTypeExpression4() {
String query = "SELECT e FROM CompUser e where TYPE(e) = MaleUser"; String query = "SELECT e FROM CompUser e where TYPE(e) = MaleUser";
CriteriaQuery<?> cq = cb.createQuery(); CriteriaQuery<CompUser> cq = cb.createQuery(CompUser.class);
Root<CompUser> e = cq.from(CompUser.class); Root<CompUser> e = cq.from(CompUser.class);
// cq.select(e); cq.select(e);
cq.where(cb.equal(e.type(), cb.literal(MaleUser.class))); cq.where(cb.equal(e.type(), cb.literal(MaleUser.class)));
assertEquivalence(cq, query); assertEquivalence(cq, query);
@ -581,9 +577,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testTypeExpression7() { public void testTypeExpression7() {
String query = "SELECT TYPE(a.b) FROM A a"; String query = "SELECT TYPE(a.b) FROM A a";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<A> a = q.from(A.class); Root<A> a = q.from(A.class);
// q.select(a.get(A_.b).type()); q.multiselect(a.get(A_.b).type());
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -591,9 +587,9 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testTypeExpression8() { public void testTypeExpression8() {
String query = "SELECT MaleUser FROM A a"; String query = "SELECT MaleUser FROM A a";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Class> q = cb.createQuery(Class.class);
Root<A> a = q.from(A.class); Root<A> a = q.from(A.class);
// q.select(cb.literal(MaleUser.class)); q.multiselect(cb.literal(MaleUser.class));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -602,36 +598,34 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
String query = "SELECT " String query = "SELECT "
+ " CASE TYPE(e) WHEN FemaleUser THEN 'Female' " + " CASE TYPE(e) WHEN FemaleUser THEN 'Female' "
+ " ELSE 'Male' END FROM CompUser e"; + " ELSE 'Male' END FROM CompUser e";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Object> q = cb.createQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(cb.selectCase(e.type()).when(FemaleUser.class, "Female") q.select(cb.selectCase(e.type())
// .otherwise("Male")); .when(FemaleUser.class, "Female")
.otherwise("Male"));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
public void testCoalesceExpressions() { public void testCoalesceExpressions() {
String query = "SELECT e.name, " String query = "SELECT e.name, COALESCE (e.address.country, 'Unknown') FROM CompUser e ORDER BY e.name DESC";
+ "COALESCE (e.address.country, 'Unknown')"
+ " FROM CompUser e ORDER BY e.name DESC";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(e.get(CompUser_.name), cb.coalesce().value( q.multiselect(e.get(CompUser_.name),
// e.get(CompUser_.address).get(Address_.country)) cb.coalesce().value(e.get(CompUser_.address).get(Address_.country)).value("Unknown"));
// .value("Unknown"));
q.orderBy(cb.desc(e.get(CompUser_.name))); q.orderBy(cb.desc(e.get(CompUser_.name)));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
public void testNullIfExpressions() { public void testNullIfExpressions() {
String query = "SELECT e.name, NULLIF (e.address.country, 'USA')" String query = "SELECT e.name, NULLIF (e.address.country, 'USA') FROM CompUser e ORDER BY e.name DESC";
+ " FROM CompUser e ORDER BY e.name DESC";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(e.get(CompUser_.name), cb.nullif(e.get(CompUser_.address).get( q.multiselect(e.get(CompUser_.name),
// Address_.country), "USA")); cb.nullif(e.get(CompUser_.address).get(Address_.country), "USA"));
q.orderBy(cb.desc(e.get(CompUser_.name))); q.orderBy(cb.desc(e.get(CompUser_.name)));
assertEquivalence(q, query); assertEquivalence(q, query);
@ -642,14 +636,15 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
+ "CASE e.address.country WHEN 'USA' THEN 'us' " + "CASE e.address.country WHEN 'USA' THEN 'us' "
+ " ELSE 'non-us' END, e.address.country " + " ELSE 'non-us' END, e.address.country "
+ " FROM CompUser e"; + " FROM CompUser e";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
Expression<Integer> cage = cb.sum(e.get(CompUser_.age), 1); Expression<Integer> cage = cb.sum(e.get(CompUser_.age), 1);
Expression d2 = cb.selectCase( Expression d2 = cb.selectCase(
e.get(CompUser_.address).get(Address_.country)).when("USA", e.get(CompUser_.address).get(Address_.country)).when("USA",
"us").otherwise("non-us"); "us").otherwise("non-us");
// q.select(e.get(CompUser_.name), cage, d2, e.get(CompUser_.address).get( q.multiselect(e.get(CompUser_.name), cage, d2, e.get(CompUser_.address).get(
// Address_.country)); Address_.country));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -660,15 +655,15 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
+ " THEN 'United-States' " + " THEN 'United-States' "
+ " ELSE e.address.country END," + " e.address.country " + " ELSE e.address.country END," + " e.address.country "
+ " FROM CompUser e"; + " FROM CompUser e";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
Expression cage = cb.sum(e.get(CompUser_.age), 1); Expression cage = cb.sum(e.get(CompUser_.age), 1);
Expression d2 = cb.selectCase( Expression d2 = cb.selectCase(
e.get(CompUser_.address).get(Address_.country)).when("USA", e.get(CompUser_.address).get(Address_.country)).when("USA",
"United-States").otherwise( "United-States").otherwise(
e.get(CompUser_.address).get(Address_.country)); e.get(CompUser_.address).get(Address_.country));
// q.select(e.get(CompUser_.name), cage, d2, e.get(CompUser_.address).get( q.multiselect(e.get(CompUser_.name), cage, d2, e.get(CompUser_.address).get(
// Address_.country)); Address_.country));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -679,11 +674,11 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
+ " ELSE 'Male' END" + " ELSE 'Male' END"
+ " FROM CompUser e WHERE e.name like 'S%' " + " FROM CompUser e WHERE e.name like 'S%' "
+ " ORDER BY e.name DESC"; + " ORDER BY e.name DESC";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(e.get(CompUser_.name), q.multiselect(e.get(CompUser_.name),
// cb.selectCase(e.type()).when(FemaleUser.class, "Female") cb.selectCase(e.type()).when(FemaleUser.class, "Female")
// .otherwise("Male")); .otherwise("Male"));
q.where(cb.like(e.get(CompUser_.name), "S%")); q.where(cb.like(e.get(CompUser_.name), "S%"));
q.orderBy(cb.desc(e.get(CompUser_.name))); q.orderBy(cb.desc(e.get(CompUser_.name)));
@ -694,13 +689,13 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
String query = "SELECT e.name, CASE e.address.country WHEN 'USA'" String query = "SELECT e.name, CASE e.address.country WHEN 'USA'"
+ " THEN true ELSE false END," + " THEN true ELSE false END,"
+ " e.address.country FROM CompUser e"; + " e.address.country FROM CompUser e";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
Expression b = cb.selectCase( Expression b = cb.selectCase(
e.get(CompUser_.address).get(Address_.country)).when("USA", e.get(CompUser_.address).get(Address_.country)).when("USA",
true).otherwise(false); true).otherwise(false);
// q.select(e.get(CompUser_.name), b, e.get(CompUser_.address).get( q.multiselect(e.get(CompUser_.name), b, e.get(CompUser_.address).get(
// Address_.country)); Address_.country));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -710,14 +705,14 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
+ " CASE WHEN e.age > 30 THEN e.age - 1 " + " CASE WHEN e.age > 30 THEN e.age - 1 "
+ " WHEN e.age < 15 THEN e.age + 1 ELSE e.age + 0 " + " WHEN e.age < 15 THEN e.age + 1 ELSE e.age + 0 "
+ " END FROM CompUser e"; + " END FROM CompUser e";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
Expression cage = cb.selectCase().when(cb.gt(e.get(CompUser_.age), 30), Expression cage = cb.selectCase().when(cb.gt(e.get(CompUser_.age), 30),
cb.diff(e.get(CompUser_.age), 1)).when( cb.diff(e.get(CompUser_.age), 1)).when(
cb.lt(e.get(CompUser_.age), 15), cb.lt(e.get(CompUser_.age), 15),
cb.sum(e.get(CompUser_.age), 1)).otherwise( cb.sum(e.get(CompUser_.age), 1)).otherwise(
cb.sum(e.get(CompUser_.age), 0)); cb.sum(e.get(CompUser_.age), 0));
// q.select(e.get(CompUser_.name), e.get(CompUser_.age), cage); q.multiselect(e.get(CompUser_.name), e.get(CompUser_.age), cage);
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -729,7 +724,7 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
+ " ELSE 'Non United-States' END," + " ELSE 'Non United-States' END,"
+ " e.address.country " + " e.address.country "
+ " FROM CompUser e"; + " FROM CompUser e";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
Expression d2 = cb.selectCase() Expression d2 = cb.selectCase()
.when( .when(
@ -738,8 +733,8 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
"USA"), "United-States").otherwise( "USA"), "United-States").otherwise(
"Non United-States"); "Non United-States");
Expression cage = cb.sum(e.get(CompUser_.age), 1); Expression cage = cb.sum(e.get(CompUser_.age), 1);
// q.select(e.get(CompUser_.name), cage, d2, e.get(CompUser_.address).get( q.multiselect(e.get(CompUser_.name), cage, d2, e.get(CompUser_.address).get(
// Address_.country)); Address_.country));
assertEquivalence(q, query); assertEquivalence(q, query);
} }
@ -756,13 +751,13 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
+ "org.apache.openjpa.persistence.criteria.CompUser$" + "org.apache.openjpa.persistence.criteria.CompUser$"
+ "CreditRating.EXCELLENT" + "CreditRating.EXCELLENT"
+ " END FROM CompUser e ORDER BY e.age"; + " END FROM CompUser e ORDER BY e.age";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(e.get(CompUser_.name), cb.selectCase().when( q.multiselect(e.get(CompUser_.name), cb.selectCase().when(
// cb.equal(e.get(CompUser_.age), 11), CompUser.CreditRating.POOR) cb.equal(e.get(CompUser_.age), 11), CompUser.CreditRating.POOR)
// .when(cb.equal(e.get(CompUser_.age), 35), .when(cb.equal(e.get(CompUser_.age), 35),
// CompUser.CreditRating.GOOD).otherwise( CompUser.CreditRating.GOOD).otherwise(
// CompUser.CreditRating.EXCELLENT)); CompUser.CreditRating.EXCELLENT));
q.orderBy(cb.asc(e.get(CompUser_.age))); q.orderBy(cb.asc(e.get(CompUser_.age)));
@ -787,21 +782,20 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
+ "CreditRating.EXCELLENT" + "CreditRating.EXCELLENT"
+ " END from CompUser e1" + " END from CompUser e1"
+ " where e.userid = e1.userid) ORDER BY e.age"; + " where e.userid = e1.userid) ORDER BY e.age";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<CompUser> e = q.from(CompUser.class); Root<CompUser> e = q.from(CompUser.class);
// q.select(e.get(CompUser_.name), e.get(CompUser_.creditRating)); q.multiselect(e.get(CompUser_.name), e.get(CompUser_.creditRating));
q.orderBy(cb.asc(e.get(CompUser_.age))); q.orderBy(cb.asc(e.get(CompUser_.age)));
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Object> sq = q.subquery(Object.class);
Root<CompUser> e1 = sq.from(CompUser.class); Root<CompUser> e1 = sq.from(CompUser.class);
sq.where(cb.equal(e.get(CompUser_.userid), e1.get(CompUser_.userid))); sq.where(cb.equal(e.get(CompUser_.userid), e1.get(CompUser_.userid)));
q.where(cb.equal(e.get(CompUser_.creditRating), q.where(cb.equal(e.get(CompUser_.creditRating),
// sq.select( sq.select(
cb.selectCase().when(cb.equal(e1.get(CompUser_.age), 11), cb.selectCase()
CompUser.CreditRating.POOR).when( .when(cb.equal(e1.get(CompUser_.age), 11), CompUser.CreditRating.POOR)
cb.equal(e1.get(CompUser_.age), 35), .when(cb.equal(e1.get(CompUser_.age), 35), CompUser.CreditRating.GOOD)
CompUser.CreditRating.GOOD).otherwise( .otherwise(CompUser.CreditRating.EXCELLENT))));
CompUser.CreditRating.EXCELLENT)));
q.orderBy(cb.asc(e.get(CompUser_.age))); q.orderBy(cb.asc(e.get(CompUser_.age)));

View File

@ -25,14 +25,17 @@ import java.util.List;
import javax.persistence.Parameter; import javax.persistence.Parameter;
import javax.persistence.Tuple; import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join; import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType; import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.ListJoin; import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.MapJoin; import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import javax.persistence.criteria.SetJoin; import javax.persistence.criteria.SetJoin;
import javax.persistence.criteria.Subquery; import javax.persistence.criteria.Subquery;
import javax.persistence.criteria.QueryBuilder.Case; import javax.persistence.criteria.QueryBuilder.Case;
import javax.persistence.criteria.QueryBuilder.SimpleCase;
import org.apache.openjpa.persistence.test.AllowFailure; import org.apache.openjpa.persistence.test.AllowFailure;
@ -107,28 +110,29 @@ public class TestTypesafeCriteria extends CriteriaTest {
public void testProjection() { public void testProjection() {
String jpql = "select a.balance,a.loan from Account a"; String jpql = "select a.balance,a.loan from Account a";
CriteriaQuery<?> c = cb.createQuery(); CriteriaQuery<Tuple> c = cb.createTupleQuery();
Root<Account> account = c.from(Account.class); Root<Account> account = c.from(Account.class);
// c.select(account.get(Account_.balance), account.get(Account_.loan)); c.multiselect(account.get(Account_.balance), account.get(Account_.loan));
assertEquivalence(c, jpql); assertEquivalence(c, jpql);
} }
public void testAbsExpression() { public void testAbsExpression() {
CriteriaQuery<?> c = cb.createQuery(); String jpql = "select a from Account a where abs(a.balance)=100";
CriteriaQuery<Account> c = cb.createQuery(Account.class);
Root<Account> account = c.from(Account.class); Root<Account> account = c.from(Account.class);
String jpql = "select a from Account a where abs(a.balance)=100"; c.select(account).where(cb.equal(cb.abs(account.get(Account_.balance)), 100));
// c.select(account).where(
// cb.equal(cb.abs(account.get(Account_.balance)), 100));
assertEquivalence(c, jpql); assertEquivalence(c, jpql);
} }
public void testAvgExpression() { public void testAvgExpression() {
CriteriaQuery<?> c = cb.createQuery(); String jpql = "select avg(a.balance) from Account a";
CriteriaQuery<Double> c = cb.createQuery(Double.class);
Root<Account> account = c.from(Account.class); Root<Account> account = c.from(Account.class);
String jpql = "select avg(a.balance) from Account a"; c.select(cb.avg(account.get(Account_.balance)));
// c.select(cb.avg(account.get(Account_.balance)));
assertEquivalence(c, jpql); assertEquivalence(c, jpql);
} }
@ -330,9 +334,9 @@ public class TestTypesafeCriteria extends CriteriaTest {
public void testTypeExpression() { public void testTypeExpression() {
String jpql = "SELECT TYPE(e) FROM Employee e WHERE TYPE(e) <> Exempt"; String jpql = "SELECT TYPE(e) FROM Employee e WHERE TYPE(e) <> Exempt";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Object> q = cb.createQuery();
Root<Employee> emp = q.from(Employee.class); Root<Employee> emp = q.from(Employee.class);
// q.select(emp.type()).where(cb.notEqual(emp.type(), Exempt.class)); q.multiselect(emp.type()).where(cb.notEqual(emp.type(), Exempt.class));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -372,30 +376,28 @@ public class TestTypesafeCriteria extends CriteriaTest {
String jpql = "SELECT SIZE(d.employees) FROM Department d " String jpql = "SELECT SIZE(d.employees) FROM Department d "
+ "WHERE d.name = 'Sales'"; + "WHERE d.name = 'Sales'";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Integer> q = cb.createQuery(Integer.class);
Root<Department> d = q.from(Department.class); Root<Department> d = q.from(Department.class);
q.where(cb.equal(d.get(Department_.name), "Sales")); q.where(cb.equal(d.get(Department_.name), "Sales"));
// q.select(cb.size(d.get(Department_.employees))); q.select(cb.size(d.get(Department_.employees)));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
public void testCaseExpression() { public void testCaseExpression() {
String jpql = String jpql = "SELECT e.name, CASE "
"SELECT e.name, CASE WHEN e.rating = 1 THEN e.salary * 1.1 " + "WHEN e.rating = 1 THEN e.salary * 1.1 "
+ "WHEN e.rating = 2 THEN e.salary * 1.2 ELSE e.salary * " + "WHEN e.rating = 2 THEN e.salary * 1.2 "
+ "1.01 END " + "ELSE e.salary * 1.01 END "
+ "FROM Employee e WHERE e.department.name = 'Engineering'"; + "FROM Employee e WHERE e.department.name = 'Engineering'";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<?> q = cb.createQuery();
Root<Employee> e = q.from(Employee.class); Root<Employee> e = q.from(Employee.class);
q.where(cb.equal(e.get(Employee_.department).get(Department_.name), q.where(cb.equal(e.get(Employee_.department).get(Department_.name), "Engineering"));
"Engineering")); q.multiselect(e.get(Employee_.name),
// q.select(e.get(Employee_.name), cb.multiselect(Case().when( cb.selectCase()
// cb.equal(e.get(Employee_.rating), 1), .when(cb.equal(e.get(Employee_.rating), 1), cb.prod(e.get(Employee_.salary), 1.1))
// cb.prod(e.get(Employee_.salary), 1.1)).when( .when(cb.equal(e.get(Employee_.rating), 2), cb.prod(e.get(Employee_.salary), 1.2))
// cb.equal(e.get(Employee_.rating), 2), .otherwise(cb.prod(e.get(Employee_.salary), 1.01)));
// cb.prod(e.get(Employee_.salary), 1.2)).otherwise(
// cb.prod(e.get(Employee_.salary), 1.01))));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -440,14 +442,12 @@ public class TestTypesafeCriteria extends CriteriaTest {
+ "FROM Employee e WHERE e.department.name = 'Engineering'"; + "FROM Employee e WHERE e.department.name = 'Engineering'";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<?> q = cb.createQuery();
Root<Employee> e = q.from(Employee.class); Root<Employee> e = q.from(Employee.class);
q.where(cb.equal(e.get(Employee_.department).get(Department_.name), q.where(cb.equal(e.get(Employee_.department).get(Department_.name), "Engineering"));
"Engineering")); q.multiselect(e.get(Employee_.name),
// q.select(e.get(Employee_.name), cb.multiselect(Case().when( cb.selectCase()
// cb.equal(e.get(Employee_.rating), 1), .when(cb.equal(e.get(Employee_.rating), 1), cb.prod(e.get(Employee_.salary), 1.1))
// cb.prod(e.get(Employee_.salary), 1.1)).when( .when(cb.equal(e.get(Employee_.rating), 2), cb.prod(e.get(Employee_.salary), 1.2))
// cb.equal(e.get(Employee_.rating), 2), .otherwise(cb.prod(e.get(Employee_.salary), 1.01)));
// cb.prod(e.get(Employee_.salary), 1.2)).otherwise(
// cb.prod(e.get(Employee_.salary), 1.01)));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -457,14 +457,16 @@ public class TestTypesafeCriteria extends CriteriaTest {
+ "WHEN 1 THEN e.salary * 1.1 " + "WHEN 1 THEN e.salary * 1.1 "
+ "WHEN 2 THEN e.salary * 1.2 ELSE e.salary * 1.01 END " + "WHEN 2 THEN e.salary * 1.2 ELSE e.salary * 1.01 END "
+ "FROM Employee e WHERE e.department.name = 'Engineering'"; + "FROM Employee e WHERE e.department.name = 'Engineering'";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Employee> e = q.from(Employee.class); Root<Employee> e = q.from(Employee.class);
q.where(cb.equal(e.get(Employee_.department).get(Department_.name), q.where(cb.equal(e.get(Employee_.department).get(Department_.name), "Engineering"));
"Engineering")); Expression<Long> salary = e.get(Employee_.salary);
// q.select(e.get(Employee_.name), cb.multiselect(Case(e.get(Employee_.rating)) Expression<Integer> rating = e.get(Employee_.rating);
// .when(1, cb.prod(e.get(Employee_.salary), 1.1)).when(2, q.multiselect(e.get(Employee_.name),
// cb.prod(e.get(Employee_.salary), 1.2)).otherwise( cb.selectCase(rating).
// cb.prod(e.get(Employee_.salary), 1.01))); when(1, cb.prod(salary, 1.1))
.when(2, cb.prod(salary, 1.2))
.otherwise(cb.prod(salary, 1.01)));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -473,46 +475,47 @@ public class TestTypesafeCriteria extends CriteriaTest {
String jpql = "SELECT e.name, CASE e.rating WHEN 1 THEN 10 " String jpql = "SELECT e.name, CASE e.rating WHEN 1 THEN 10 "
+ "WHEN 2 THEN 20 ELSE 30 END " + "WHEN 2 THEN 20 ELSE 30 END "
+ "FROM Employee e WHERE e.department.name = 'Engineering'"; + "FROM Employee e WHERE e.department.name = 'Engineering'";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Employee> e = q.from(Employee.class); Root<Employee> e = q.from(Employee.class);
q.where(cb.equal(e.get(Employee_.department).get(Department_.name), Expression<Integer> rating = e.get(Employee_.rating);
"Engineering")); q.where(cb.equal(e.get(Employee_.department).get(Department_.name), "Engineering"));
// q.select(e.get(Employee_.name), cb.multiselect(Case(e.get(Employee_.rating)) q.multiselect(e.get(Employee_.name),
// .when(1, 10).when(2, 20).otherwise(30)); cb.selectCase(rating)
.when(1, 10)
.when(2, 20)
.otherwise(30));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
public void testLiterals() { public void testLiterals() {
String jpql = "SELECT p FROM Person p where 'Joe' MEMBER OF " + String jpql = "SELECT p FROM Person p where 'Joe' MEMBER OF p.nickNames";
"p.nickNames"; CriteriaQuery<Person> q = cb.createQuery(Person.class);
CriteriaQuery<?> q = cb.createQuery();
Root<Person> p = q.from(Person.class); Root<Person> p = q.from(Person.class);
// q.select(p).where( q.select(p).where(cb.isMember(cb.literal("Joe"), p.get(Person_.nickNames)));
// cb.isMember(cb.literal("Joe"), p.get(Person_.nickNames)));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
public void testParameters1() { public void testParameters1() {
String jpql = "SELECT c FROM Customer c Where c.status = :stat"; String jpql = "SELECT c FROM Customer c Where c.status = :stat";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Parameter<Integer> param = cb.parameter(Integer.class, "stat"); Parameter<Integer> param = cb.parameter(Integer.class, "stat");
// q.select(c).where(cb.equal(c.get(Customer_.status), param)); q.select(c).where(cb.equal(c.get(Customer_.status), param));
assertEquivalence(q, jpql, new String[] { "stat" }, new Object[] { 1 }); assertEquivalence(q, jpql, new String[] { "stat" }, new Object[] { 1 });
} }
public void testParameters2() { public void testParameters2() {
String jpql = "SELECT c FROM Customer c Where c.status = :stat AND " String jpql = "SELECT c FROM Customer c Where c.status = :stat AND c.name = :name";
+ "c.name = :name";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Parameter<Integer> param1 = cb.parameter(Integer.class, "stat"); Parameter<Integer> param1 = cb.parameter(Integer.class, "stat");
Parameter<String> param2 = cb.parameter(String.class, "name"); Parameter<String> param2 = cb.parameter(String.class, "name");
// q.select(c).where( q.select(c).where(cb.and(cb.equal(c.get(Customer_.status), param1),
// cb.and(cb.equal(c.get(Customer_.status), param1), cb.equal(c cb.equal(c.get(Customer_.name), param2)));
// .get(Customer_.name), param2)));
assertEquivalence(q, jpql, new String[] { "stat", "name" }, assertEquivalence(q, jpql, new String[] { "stat", "name" },
new Object[] { 1, "test" }); new Object[] { 1, "test" });
@ -520,22 +523,24 @@ public class TestTypesafeCriteria extends CriteriaTest {
public void testParameters3() { public void testParameters3() {
String jpql = "SELECT c FROM Customer c Where c.status = :stat"; String jpql = "SELECT c FROM Customer c Where c.status = :stat";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Parameter<Integer> param = cb.parameter(Integer.class, "stat"); Parameter<Integer> param = cb.parameter(Integer.class, "stat");
// q.select(c).where(cb.equal(c.get(Customer_.status), param)); q.select(c).where(cb.equal(c.get(Customer_.status), param));
assertEquivalence(q, jpql, new String[]{"stat"}, new Object[] { 1 }); assertEquivalence(q, jpql, new String[]{"stat"}, new Object[] { 1 });
} }
public void testParameters4() { public void testParameters4() {
String jpql = "SELECT c FROM Customer c Where c.status = :stat AND " String jpql = "SELECT c FROM Customer c Where c.status = :stat AND c.name = :name";
+ "c.name = :name";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Parameter<Integer> param1 = cb.parameter(Integer.class, "stat"); Parameter<Integer> param1 = cb.parameter(Integer.class, "stat");
Parameter<String> param2 = cb.parameter(String.class, "name"); Parameter<String> param2 = cb.parameter(String.class, "name");
// q.select(c).where(cb.and(cb.equal(c.get(Customer_.status), param1), q.select(c).where(cb.and(cb.equal(c.get(Customer_.status), param1),
// cb.equal(c.get(Customer_.name), param2))); cb.equal(c.get(Customer_.name), param2)));
assertEquivalence(q, jpql, new String[]{"stat", "name"}, assertEquivalence(q, jpql, new String[]{"stat", "name"},
new Object[] { 1, "test" }); new Object[] { 1, "test" });
} }
@ -543,16 +548,16 @@ public class TestTypesafeCriteria extends CriteriaTest {
@AllowFailure(message="collection valued parameter does not work in in()") @AllowFailure(message="collection valued parameter does not work in in()")
public void testParameters5() { public void testParameters5() {
String jpql = "SELECT c FROM Customer c Where c.status IN (:coll)"; String jpql = "SELECT c FROM Customer c Where c.status IN (:coll)";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Parameter<List> param1 = cb.parameter(List.class, "coll"); ParameterExpression<List> param1 = cb.parameter(List.class, "coll");
q.where(c.get(Customer_.status).in(param1)); q.where(c.get(Customer_.status).in(param1));
// q.select(c).where(cb.in(c.get(Customer_.status)).value(params1)); q.select(c);
List vals = new ArrayList(); List vals = new ArrayList();
vals.add(1); vals.add(1);
vals.add(2); vals.add(2);
assertEquivalence(q, jpql, new String[] {"coll"}, assertEquivalence(q, jpql, new String[] {"coll"}, new Object[] {vals});
new Object[] {vals});
} }
@AllowFailure(message="Generates invalid SQL") @AllowFailure(message="Generates invalid SQL")
@ -560,29 +565,27 @@ public class TestTypesafeCriteria extends CriteriaTest {
String jpql = "SELECT v.location.street, KEY(i).title, VALUE(i) FROM " String jpql = "SELECT v.location.street, KEY(i).title, VALUE(i) FROM "
+ "VideoStore v JOIN v.videoInventory i WHERE v.location.zipCode = " + "VideoStore v JOIN v.videoInventory i WHERE v.location.zipCode = "
+ "'94301' AND VALUE(i) > 0"; + "'94301' AND VALUE(i) > 0";
CriteriaQuery<?> q = cb.createQuery();
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<VideoStore> v = q.from(VideoStore.class); Root<VideoStore> v = q.from(VideoStore.class);
MapJoin<VideoStore, Movie, Integer> inv = v MapJoin<VideoStore, Movie, Integer> i = v.join(VideoStore_.videoInventory);
.join(VideoStore_.videoInventory);
q.where(cb.and( q.where(cb.and(
cb.equal(v.get(VideoStore_.location).get(Address_.zipCode), cb.equal(v.get(VideoStore_.location).get(Address_.zipCode), "94301"),
"94301"), cb.gt(inv.value(), 0))); cb.gt(i.value(), 0)));
// q.select(v.get(VideoStore_.location).get(Address_.street), inv.key() q.multiselect(v.get(VideoStore_.location).get(Address_.street),
// .get(Movie_.title), inv.value()); i.key().get(Movie_.title),
i.value());
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
public void testNewConstruct() { public void testNewConstruct() {
String jpql = "SELECT NEW CustomerDetails(c.id, c.status) FROM " String jpql = "SELECT NEW CustomerDetails(c.id, c.status) FROM Customer c";
+ "Customer c";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<CustomerDetails> q = cb.createQuery(CustomerDetails.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
// q.select(cb.multiselect(CustomerDetails.class, c.get(Customer_.id), q.select(cb.construct(CustomerDetails.class, c.get(Customer_.id), c.get(Customer_.status)));
// c.get(Customer_.status))
// );
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -626,13 +629,13 @@ public class TestTypesafeCriteria extends CriteriaTest {
+ "goodCustomer.balanceOwed < (SELECT AVG(c.balanceOwed) " + "goodCustomer.balanceOwed < (SELECT AVG(c.balanceOwed) "
+ " FROM " + " FROM "
+ "Customer c)"; + "Customer c)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> goodCustomer = q.from(Customer.class); Root<Customer> goodCustomer = q.from(Customer.class);
Subquery<Double> sq = q.subquery(Double.class); Subquery<Double> sq = q.subquery(Double.class);
Root<Customer> c = sq.from(Customer.class); Root<Customer> c = sq.from(Customer.class);
q.where(cb.lt(goodCustomer.get(Customer_.balanceOwed), sq.select(cb q.where(cb.lt(goodCustomer.get(Customer_.balanceOwed), sq.select(cb
.avg(c.get(Customer_.balanceOwed))))); .avg(c.get(Customer_.balanceOwed)))));
// q.select(goodCustomer); q.select(goodCustomer);
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -641,14 +644,14 @@ public class TestTypesafeCriteria extends CriteriaTest {
String jpql = "SELECT DISTINCT emp FROM Employee emp WHERE EXISTS (" String jpql = "SELECT DISTINCT emp FROM Employee emp WHERE EXISTS ("
+ "SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp =" + "SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp ="
+ " emp.spouse)"; + " emp.spouse)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Employee> q = cb.createQuery(Employee.class);
Root<Employee> emp = q.from(Employee.class); Root<Employee> emp = q.from(Employee.class);
Subquery<Employee> sq = q.subquery(Employee.class); Subquery<Employee> sq = q.subquery(Employee.class);
Root<Employee> spouseEmp = sq.from(Employee.class); Root<Employee> spouseEmp = sq.from(Employee.class);
sq.select(spouseEmp); sq.select(spouseEmp);
sq.where(cb.equal(spouseEmp, emp.get(Employee_.spouse))); sq.where(cb.equal(spouseEmp, emp.get(Employee_.spouse)));
q.where(cb.exists(sq)); q.where(cb.exists(sq));
// q.select(emp).distinct(true); q.select(emp).distinct(true);
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -657,9 +660,9 @@ public class TestTypesafeCriteria extends CriteriaTest {
String jpql = "SELECT emp FROM Employee emp WHERE emp.salary > ALL (" String jpql = "SELECT emp FROM Employee emp WHERE emp.salary > ALL ("
+ "SELECT m.salary FROM Manager m WHERE m.department = " + "SELECT m.salary FROM Manager m WHERE m.department = "
+ "emp.department)"; + "emp.department)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Employee> q = cb.createQuery(Employee.class);
Root<Employee> emp = q.from(Employee.class); Root<Employee> emp = q.from(Employee.class);
// q.select(emp); q.select(emp);
Subquery<BigDecimal> sq = q.subquery(BigDecimal.class); Subquery<BigDecimal> sq = q.subquery(BigDecimal.class);
Root<Manager> m = sq.from(Manager.class); Root<Manager> m = sq.from(Manager.class);
sq.select(m.get(Manager_.salary)); sq.select(m.get(Manager_.salary));
@ -673,9 +676,9 @@ public class TestTypesafeCriteria extends CriteriaTest {
public void testSubqueries4() { public void testSubqueries4() {
String jpql = "SELECT c FROM Customer c WHERE " String jpql = "SELECT c FROM Customer c WHERE "
+ "(SELECT COUNT(o) FROM c.orders o) > 10"; + "(SELECT COUNT(o) FROM c.orders o) > 10";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> c1 = q.from(Customer.class); Root<Customer> c1 = q.from(Customer.class);
// q.select(c1); q.select(c1);
Subquery<Long> sq3 = q.subquery(Long.class); Subquery<Long> sq3 = q.subquery(Long.class);
Root<Customer> c2 = sq3.correlate(c1); Root<Customer> c2 = sq3.correlate(c1);
Join<Customer, Order> o = c2.join(Customer_.orders); Join<Customer, Order> o = c2.join(Customer_.orders);
@ -687,9 +690,9 @@ public class TestTypesafeCriteria extends CriteriaTest {
public void testSubqueries5() { public void testSubqueries5() {
String jpql = "SELECT o FROM Order o WHERE 10000 < ALL (" String jpql = "SELECT o FROM Order o WHERE 10000 < ALL ("
+ "SELECT a.balance FROM o.customer c JOIN c.accounts a)"; + "SELECT a.balance FROM o.customer c JOIN c.accounts a)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Order> q = cb.createQuery(Order.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o); q.select(o);
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Root<Order> osq = sq.correlate(o); Root<Order> osq = sq.correlate(o);
Join<Order, Customer> c = osq.join(Order_.customer); Join<Order, Customer> c = osq.join(Order_.customer);
@ -700,13 +703,12 @@ public class TestTypesafeCriteria extends CriteriaTest {
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@AllowFailure(message="Root of subquery.delgate is not set")
public void testSubqueries6() { public void testSubqueries6() {
String jpql = "SELECT o FROM Order o JOIN o.customer c WHERE 10000 < " String jpql = "SELECT o FROM Order o JOIN o.customer c WHERE 10000 < "
+ "ALL (SELECT a.balance FROM c.accounts a)"; + "ALL (SELECT a.balance FROM c.accounts a)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Order> q = cb.createQuery(Order.class);
Root<Order> o = q.from(Order.class); Root<Order> o = q.from(Order.class);
// q.select(o); q.select(o);
Join<Order, Customer> c = o.join(Order_.customer); Join<Order, Customer> c = o.join(Order_.customer);
Subquery<Integer> sq = q.subquery(Integer.class); Subquery<Integer> sq = q.subquery(Integer.class);
Join<Order, Customer> csq = sq.correlate(c); Join<Order, Customer> csq = sq.correlate(c);
@ -720,12 +722,12 @@ public class TestTypesafeCriteria extends CriteriaTest {
public void testGroupByAndHaving() { public void testGroupByAndHaving() {
String jpql = "SELECT c.status, AVG(c.filledOrderCount), COUNT(c) FROM " String jpql = "SELECT c.status, AVG(c.filledOrderCount), COUNT(c) FROM "
+ "Customer c GROUP BY c.status HAVING c.status IN (1, 2)"; + "Customer c GROUP BY c.status HAVING c.status IN (1, 2)";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
q.groupBy(c.get(Customer_.status)); q.groupBy(c.get(Customer_.status));
q.having(cb.in(c.get(Customer_.status)).value(1).value(2)); q.having(cb.in(c.get(Customer_.status)).value(1).value(2));
// q.select(c.get(Customer_.status), cb.avg(c q.multiselect(c.get(Customer_.status), cb.avg(c
// .get(Customer_.filledOrderCount)), cb.count(c)); .get(Customer_.filledOrderCount)), cb.count(c));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -734,14 +736,14 @@ public class TestTypesafeCriteria extends CriteriaTest {
String jpql = "SELECT o FROM Customer c JOIN c.orders o " String jpql = "SELECT o FROM Customer c JOIN c.orders o "
+ "JOIN c.address a WHERE a.state = 'CA' ORDER BY o.quantity DESC, " + "JOIN c.address a WHERE a.state = 'CA' ORDER BY o.quantity DESC, "
+ "o.totalCost"; + "o.totalCost";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Order> q = cb.createQuery(Order.class);
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(Customer_.orders); Join<Customer, Order> o = c.join(Customer_.orders);
Join<Customer, Address> a = c.join(Customer_.address); Join<Customer, Address> a = c.join(Customer_.address);
q.where(cb.equal(a.get(Address_.state), "CA")); q.where(cb.equal(a.get(Address_.state), "CA"));
q.orderBy(cb.desc(o.get(Order_.quantity)), cb.asc(o q.orderBy(cb.desc(o.get(Order_.quantity)), cb.asc(o
.get(Order_.totalCost))); .get(Order_.totalCost)));
// q.select(o); q.select(o);
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -750,14 +752,14 @@ public class TestTypesafeCriteria extends CriteriaTest {
String jpql = "SELECT o.quantity, a.zipCode FROM Customer c " String jpql = "SELECT o.quantity, a.zipCode FROM Customer c "
+ "JOIN c.orders o JOIN c.address a WHERE a.state = 'CA' " + "JOIN c.orders o JOIN c.address a WHERE a.state = 'CA' "
+ "ORDER BY o.quantity, a.zipCode"; + "ORDER BY o.quantity, a.zipCode";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(Customer_.orders); Join<Customer, Order> o = c.join(Customer_.orders);
Join<Customer, Address> a = c.join(Customer_.address); Join<Customer, Address> a = c.join(Customer_.address);
q.where(cb.equal(a.get(Address_.state), "CA")); q.where(cb.equal(a.get(Address_.state), "CA"));
q.orderBy(cb.asc(o.get(Order_.quantity)), cb.asc(a q.orderBy(cb.asc(o.get(Order_.quantity)), cb.asc(a
.get(Address_.zipCode))); .get(Address_.zipCode)));
// q.select(o.get(Order_.quantity), a.get(Address_.zipCode)); q.multiselect(o.get(Order_.quantity), a.get(Address_.zipCode));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
@ -767,29 +769,29 @@ public class TestTypesafeCriteria extends CriteriaTest {
+ "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a " + "a.zipCode FROM Customer c JOIN c.orders o JOIN c.address a "
+ "WHERE a.state = 'CA' AND a.county = 'Santa Clara' " + "WHERE a.state = 'CA' AND a.county = 'Santa Clara' "
+ "ORDER BY o.quantity, taxedCost, a.zipCode"; + "ORDER BY o.quantity, taxedCost, a.zipCode";
CriteriaQuery<?> q = cb.createQuery(); CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
Join<Customer, Order> o = c.join(Customer_.orders); Join<Customer, Order> o = c.join(Customer_.orders);
Join<Customer, Address> a = c.join(Customer_.address); Join<Customer, Address> a = c.join(Customer_.address);
q.where(cb.equal(a.get(Address_.state), "CA"), cb.equal(a Expression<Double> taxedCost = cb.prod(o.get(Order_.totalCost), 1.08);
.get(Address_.county), "Santa Clara")); taxedCost.setAlias("taxedCost");
q.orderBy(cb.asc(o.get(Order_.quantity)), cb.asc(cb.prod( q.where(cb.equal(a.get(Address_.state), "CA"),
o.get(Order_.totalCost), 1.08)), cb.equal(a.get(Address_.county), "Santa Clara"));
q.orderBy(cb.asc(o.get(Order_.quantity)),
cb.asc(taxedCost),
cb.asc(a.get(Address_.zipCode))); cb.asc(a.get(Address_.zipCode)));
// q.select(o.get(Order_.quantity), cb.prod( q.multiselect(o.get(Order_.quantity), taxedCost, a.get(Address_.zipCode));
// o.get(Order_.totalCost), 1.08), a.get(Address_.zipCode));
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }
public void testOrdering4() { public void testOrdering4() {
String jpql = "SELECT c FROM Customer c " String jpql = "SELECT c FROM Customer c ORDER BY c.name DESC, c.status";
+ "ORDER BY c.name DESC, c.status"; CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
CriteriaQuery<?> q = cb.createQuery();
Root<Customer> c = q.from(Customer.class); Root<Customer> c = q.from(Customer.class);
q.orderBy(cb.desc(c.get(Customer_.name)), cb.asc(c q.orderBy(cb.desc(c.get(Customer_.name)),
.get(Customer_.status))); cb.asc(c.get(Customer_.status)));
// q.select(c); q.select(c);
assertEquivalence(q, jpql); assertEquivalence(q, jpql);
} }

View File

@ -12,4 +12,5 @@ import javax.persistence.metamodel.SingularAttribute;
public class ImplicitFieldAccessMappedSuperclass_ { public class ImplicitFieldAccessMappedSuperclass_ {
public static volatile SingularAttribute<ImplicitFieldAccessMappedSuperclass,Date> createTime; public static volatile SingularAttribute<ImplicitFieldAccessMappedSuperclass,Date> createTime;
public static volatile SingularAttribute<ImplicitFieldAccessMappedSuperclass,Long> id; public static volatile SingularAttribute<ImplicitFieldAccessMappedSuperclass,Long> id;
public static volatile SingularAttribute<ImplicitFieldAccessMappedSuperclass,Integer> version;
} }

View File

@ -35,7 +35,6 @@ import javax.persistence.metamodel.PluralAttribute.CollectionType;
import javax.persistence.metamodel.Type.PersistenceType; import javax.persistence.metamodel.Type.PersistenceType;
import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.enhance.identity.Book; import org.apache.openjpa.persistence.enhance.identity.Book;
import org.apache.openjpa.persistence.enhance.identity.BookId; import org.apache.openjpa.persistence.enhance.identity.BookId;
import org.apache.openjpa.persistence.enhance.identity.Library; import org.apache.openjpa.persistence.enhance.identity.Library;
@ -82,10 +81,9 @@ public class TestMetamodel extends SingleEMFTestCase {
} }
public void testMetaClassFieldsArePopulated() { public void testMetaClassFieldsArePopulated() {
EntityType<ImplicitFieldAccessSubclass> m = EntityType<ImplicitFieldAccessSubclass> m = model.entity(ImplicitFieldAccessSubclass.class);
model.entity(ImplicitFieldAccessSubclass.class);
Class<?> mCls = m.getJavaType();
assertNotNull(m); assertNotNull(m);
Class<?> mCls = m.getJavaType();
assertSame(ImplicitFieldAccessSubclass.class, mCls); assertSame(ImplicitFieldAccessSubclass.class, mCls);
Class<?> m2Cls = model.repos.getMetaModel(mCls, true); Class<?> m2Cls = model.repos.getMetaModel(mCls, true);
@ -102,7 +100,7 @@ public class TestMetamodel extends SingleEMFTestCase {
} }
} }
public void testDomainClassAreCategorizedInPersistentCategory() { public void testDomainClassCategorizedInPersistentCategory() {
assertCategory(PersistenceType.MAPPED_SUPERCLASS, ImplicitFieldAccessMappedSuperclass.class); assertCategory(PersistenceType.MAPPED_SUPERCLASS, ImplicitFieldAccessMappedSuperclass.class);
assertCategory(PersistenceType.ENTITY, ImplicitFieldAccessBase.class); assertCategory(PersistenceType.ENTITY, ImplicitFieldAccessBase.class);
assertCategory(PersistenceType.ENTITY, ImplicitFieldAccessSubclass.class); assertCategory(PersistenceType.ENTITY, ImplicitFieldAccessSubclass.class);
@ -130,19 +128,15 @@ public class TestMetamodel extends SingleEMFTestCase {
e0.getSingularAttribute("f0", ExplicitFieldAccess.class); e0.getSingularAttribute("f0", ExplicitFieldAccess.class);
fail("Expected IllegalArgumentException"); fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
// good
} }
ManagedType<ImplicitFieldAccessSubclass> e1 = model.entity( ManagedType<ImplicitFieldAccessSubclass> e1 = model.entity(ImplicitFieldAccessSubclass.class);
ImplicitFieldAccessSubclass.class);
assertNotNull(e1.getAttribute("f0")); assertNotNull(e1.getAttribute("f0"));
} }
public void testAttributeByDeclaration() { public void testAttributeByDeclaration() {
ManagedType<ImplicitFieldAccessBase> e0 = ManagedType<ImplicitFieldAccessBase> e0 = model.entity(ImplicitFieldAccessBase.class);
model.entity(ImplicitFieldAccessBase.class); ManagedType<ImplicitFieldAccessSubclass> e1 = model.entity(ImplicitFieldAccessSubclass.class);
ManagedType<ImplicitFieldAccessSubclass> e1 =
model.entity(ImplicitFieldAccessSubclass.class);
assertNotNull(e0.getAttribute("f0")); assertNotNull(e0.getAttribute("f0"));
assertNotNull(e1.getAttribute("f0")); assertNotNull(e1.getAttribute("f0"));
System.err.println(e0.getAttribute("f0")); System.err.println(e0.getAttribute("f0"));
@ -151,14 +145,13 @@ public class TestMetamodel extends SingleEMFTestCase {
assertSame(e0.getAttribute("f0"), e0.getSingularAttribute("f0", String.class)); assertSame(e0.getAttribute("f0"), e0.getSingularAttribute("f0", String.class));
assertSame(e1.getAttribute("f0"), e1.getSingularAttribute("f0", String.class)); assertSame(e1.getAttribute("f0"), e1.getSingularAttribute("f0", String.class));
assertNotSame(e0.getAttribute("f0"), e1.getAttribute("f0")); assertNotSame(e0.getAttribute("f0"), e1.getAttribute("f0"));
assertNotSame(e0.getSingularAttribute("f0", String.class), e1.getSingularAttribute("f0", assertNotSame(e0.getSingularAttribute("f0", String.class), e1.getSingularAttribute("f0", String.class));
String.class));
assertNotNull(e0.getDeclaredAttribute("f0")); assertNotNull(e0.getDeclaredAttribute("f0"));
try { try {
e1.getDeclaredAttribute("f0"); e1.getDeclaredAttribute("f0");
fail("Expected IllegalArgumentException"); fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
// good
} }
} }
@ -189,10 +182,8 @@ public class TestMetamodel extends SingleEMFTestCase {
} }
public void testPCSet() { public void testPCSet() {
ManagedType<ImplicitFieldAccessBase> e0 = ManagedType<ImplicitFieldAccessBase> e0 = model.entity(ImplicitFieldAccessBase.class);
model.entity(ImplicitFieldAccessBase.class); ManagedType<ExplicitFieldAccess> r1 = model.entity(ExplicitFieldAccess.class);
ManagedType<ExplicitFieldAccess> r1 =
model.entity(ExplicitFieldAccess.class);
SetAttribute<?, ?> relSet = e0.getSet("setRelation", ExplicitFieldAccess.class); SetAttribute<?, ?> relSet = e0.getSet("setRelation", ExplicitFieldAccess.class);
assertEquals(javax.persistence.metamodel.PluralAttribute.CollectionType.SET, relSet.getCollectionType()); assertEquals(javax.persistence.metamodel.PluralAttribute.CollectionType.SET, relSet.getCollectionType());
assertEquals(e0, relSet.getDeclaringType()); assertEquals(e0, relSet.getDeclaringType());

View File

@ -18,7 +18,7 @@
*/ */
package org.apache.openjpa.persistence; package org.apache.openjpa.persistence;
import javax.persistence.ResultItem; import javax.persistence.TupleElement;
/** /**
* A single dimension of projection in query result. * A single dimension of projection in query result.
@ -27,9 +27,9 @@ import javax.persistence.ResultItem;
* *
* @param <X> type of the result * @param <X> type of the result
*/ */
public class ResultItemImpl<X> implements ResultItem<X> { public class ResultItemImpl<X> implements TupleElement<X> {
protected String _alias; protected String _alias;
protected Class<X> _cls; protected final Class<X> _cls;
protected ResultItemImpl(Class<X> cls) { protected ResultItemImpl(Class<X> cls) {
_cls = cls; _cls = cls;

View File

@ -89,7 +89,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
* @return query object * @return query object
*/ */
public <T> CriteriaQuery<T> createQuery(Class<T> resultClass) { public <T> CriteriaQuery<T> createQuery(Class<T> resultClass) {
throw new UnsupportedOperationException(); return new CriteriaQueryImpl<T>(_model, resultClass);
} }
/** /**
@ -98,7 +98,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
* @return query object * @return query object
*/ */
public CriteriaQuery<Tuple> createTupleQuery() { public CriteriaQuery<Tuple> createTupleQuery() {
throw new UnsupportedOperationException(); return new CriteriaQueryImpl<Tuple>(_model, Tuple.class);
} }
public Object parse(String ql, ExpressionStoreQuery query) { public Object parse(String ql, ExpressionStoreQuery query) {
@ -106,22 +106,12 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
} }
public void populate(Object parsed, ExpressionStoreQuery query) { public void populate(Object parsed, ExpressionStoreQuery query) {
CriteriaQueryImpl c = (CriteriaQueryImpl) parsed; CriteriaQueryImpl<?> c = (CriteriaQueryImpl<?>) parsed;
query.invalidateCompilation(); query.invalidateCompilation();
query.getContext().setCandidateType(c.getRoot().getJavaType(), true); query.getContext().setCandidateType(c.getRoot().getJavaType(), true);
query.setQuery(parsed); query.setQuery(parsed);
} }
/**
* Define a select list item corresponding to a constructor.
* @param result class whose instance is to be constructed
* @param selections arguments to the constructor
* @return selection item
*/
public <Y> Selection<Y> construct(Class<Y> result, Selection<?>... selections) {
throw new UnsupportedOperationException();
}
public <N extends Number> Expression<N> abs(Expression<N> x) { public <N extends Number> Expression<N> abs(Expression<N> x) {
return new Expressions.Abs<N>(x); return new Expressions.Abs<N>(x);
} }
@ -199,8 +189,8 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Count(x, true); return new Expressions.Count(x, true);
} }
public CriteriaQuery createQuery() { public CriteriaQuery<Object> createQuery() {
return new CriteriaQueryImpl(_model); return new CriteriaQueryImpl<Object>(_model, Object.class);
} }
public Expression<Date> currentDate() { public Expression<Date> currentDate() {
@ -305,8 +295,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.In<T>(expression); return new Expressions.In<T>(expression);
} }
public <C extends Collection<?>> Predicate isEmpty( public <C extends Collection<?>> Predicate isEmpty(Expression<C> collection) {
Expression<C> collection) {
return new Expressions.IsEmpty(collection); return new Expressions.IsEmpty(collection);
} }
@ -314,28 +303,23 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Equal(x, false); return new Expressions.Equal(x, false);
} }
public <E, C extends Collection<E>> Predicate isMember(E e, public <E, C extends Collection<E>> Predicate isMember(E e, Expression<C> c) {
Expression<C> c) {
return new Expressions.IsMember<E>(e, c); return new Expressions.IsMember<E>(e, c);
} }
public <E, C extends Collection<E>> Predicate isMember(Expression<E> e, public <E, C extends Collection<E>> Predicate isMember(Expression<E> e, Expression<C> c) {
Expression<C> c) {
return new Expressions.IsMember<E>(e.getJavaType(), e, c); return new Expressions.IsMember<E>(e.getJavaType(), e, c);
} }
public <C extends Collection<?>> Predicate isNotEmpty( public <C extends Collection<?>> Predicate isNotEmpty(Expression<C> collection) {
Expression<C> collection) { return new Expressions.IsNotEmpty(collection);
return isEmpty(collection).negate();
} }
public <E, C extends Collection<E>> Predicate isNotMember(E e, public <E, C extends Collection<E>> Predicate isNotMember(E e, Expression<C> c) {
Expression<C> c) {
return isMember(e, c).negate(); return isMember(e, c).negate();
} }
public <E, C extends Collection<E>> Predicate isNotMember( public <E, C extends Collection<E>> Predicate isNotMember(Expression<E> e, Expression<C> c) {
Expression<E> e, Expression<C> c) {
return isMember(e, c).negate(); return isMember(e, c).negate();
} }
@ -347,8 +331,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
throw new AbstractMethodError(); throw new AbstractMethodError();
} }
public Predicate le(Expression<? extends Number> x, public Predicate le(Expression<? extends Number> x, Expression<? extends Number> y) {
Expression<? extends Number> y) {
return new Expressions.LessThanEqual(x,y); return new Expressions.LessThanEqual(x,y);
} }
@ -365,24 +348,20 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
} }
public <Y extends Comparable<Y>> Predicate lessThan( public <Y extends Comparable<Y>> Predicate lessThan(Expression<? extends Y> x, Expression<? extends Y> y) {
Expression<? extends Y> x, Expression<? extends Y> y) {
return new Expressions.LessThan(x,y); return new Expressions.LessThan(x,y);
} }
public <Y extends Comparable<Y>> Predicate lessThan( public <Y extends Comparable<Y>> Predicate lessThan(Expression<? extends Y> x, Y y) {
Expression<? extends Y> x, Y y) {
return new Expressions.LessThan(x,y); return new Expressions.LessThan(x,y);
} }
public <Y extends Comparable<Y>> Predicate lessThanOrEqualTo( public <Y extends Comparable<Y>> Predicate lessThanOrEqualTo(Expression<? extends Y> x, Expression<? extends Y> y) {
Expression<? extends Y> x, Expression<? extends Y> y) {
return new Expressions.LessThanEqual(x,y); return new Expressions.LessThanEqual(x,y);
} }
public <Y extends Comparable<Y>> Predicate lessThanOrEqualTo( public <Y extends Comparable<Y>> Predicate lessThanOrEqualTo(Expression<? extends Y> x, Y y) {
Expression<? extends Y> x, Y y) {
return new Expressions.LessThanEqual(x,y); return new Expressions.LessThanEqual(x,y);
} }
@ -394,23 +373,19 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Like(x,pattern); return new Expressions.Like(x,pattern);
} }
public Predicate like(Expression<String> x, Expression<String> pattern, public Predicate like(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar) {
Expression<Character> escapeChar) {
return new Expressions.Like(x,pattern,escapeChar); return new Expressions.Like(x,pattern,escapeChar);
} }
public Predicate like(Expression<String> x, Expression<String> pattern, public Predicate like(Expression<String> x, Expression<String> pattern, char escapeChar) {
char escapeChar) {
return new Expressions.Like(x,pattern,escapeChar); return new Expressions.Like(x,pattern,escapeChar);
} }
public Predicate like(Expression<String> x, String pattern, public Predicate like(Expression<String> x, String pattern, Expression<Character> escapeChar) {
Expression<Character> escapeChar) {
return new Expressions.Like(x,pattern,escapeChar); return new Expressions.Like(x,pattern,escapeChar);
} }
public Predicate like(Expression<String> x, String pattern, public Predicate like(Expression<String> x, String pattern, char escapeChar) {
char escapeChar) {
return new Expressions.Like(x,pattern,escapeChar); return new Expressions.Like(x,pattern,escapeChar);
} }
@ -418,8 +393,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Constant<T>(value); return new Expressions.Constant<T>(value);
} }
public Expression<Integer> locate(Expression<String> x, public Expression<Integer> locate(Expression<String> x, Expression<String> pattern) {
Expression<String> pattern) {
return new Expressions.Locate(x, pattern); return new Expressions.Locate(x, pattern);
} }
@ -428,14 +402,12 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
} }
public Expression<Integer> locate(Expression<String> x, public Expression<Integer> locate(Expression<String> x, Expression<String> pattern, Expression<Integer> from) {
Expression<String> pattern, Expression<Integer> from) {
return new Expressions.Locate(x, pattern, from); return new Expressions.Locate(x, pattern, from);
} }
public Expression<Integer> locate(Expression<String> x, String pattern, public Expression<Integer> locate(Expression<String> x, String pattern, int from) {
int from) {
return new Expressions.Locate(x, pattern, from); return new Expressions.Locate(x, pattern, from);
} }
@ -445,8 +417,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
} }
public Predicate lt(Expression<? extends Number> x, public Predicate lt(Expression<? extends Number> x, Expression<? extends Number> y) {
Expression<? extends Number> y) {
return new Expressions.LessThan(x,y); return new Expressions.LessThan(x,y);
} }
@ -462,8 +433,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Min<N>(x); return new Expressions.Min<N>(x);
} }
public Expression<Integer> mod(Expression<Integer> x, public Expression<Integer> mod(Expression<Integer> x, Expression<Integer> y) {
Expression<Integer> y) {
return new Expressions.Mod(x,y); return new Expressions.Mod(x,y);
} }
@ -499,23 +469,19 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return like(x, pattern).negate(); return like(x, pattern).negate();
} }
public Predicate notLike(Expression<String> x, Expression<String> pattern, public Predicate notLike(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar) {
Expression<Character> escapeChar) {
return like(x, pattern, escapeChar).negate(); return like(x, pattern, escapeChar).negate();
} }
public Predicate notLike(Expression<String> x, Expression<String> pattern, public Predicate notLike(Expression<String> x, Expression<String> pattern, char escapeChar) {
char escapeChar) {
return like(x, pattern, escapeChar).negate(); return like(x, pattern, escapeChar).negate();
} }
public Predicate notLike(Expression<String> x, String pattern, public Predicate notLike(Expression<String> x, String pattern, Expression<Character> escapeChar) {
Expression<Character> escapeChar) {
return like(x, pattern, escapeChar).negate(); return like(x, pattern, escapeChar).negate();
} }
public Predicate notLike(Expression<String> x, String pattern, public Predicate notLike(Expression<String> x, String pattern, char escapeChar) {
char escapeChar) {
return like(x, pattern, escapeChar).negate(); return like(x, pattern, escapeChar).negate();
} }
@ -546,23 +512,19 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new ParameterImpl<T>(paramClass, name); return new ParameterImpl<T>(paramClass, name);
} }
public <N extends Number> Expression<N> prod(Expression<? extends N> x, public <N extends Number> Expression<N> prod(Expression<? extends N> x, Expression<? extends N> y) {
Expression<? extends N> y) {
return new Expressions.Product<N>(x,y); return new Expressions.Product<N>(x,y);
} }
public <N extends Number> Expression<N> prod(Expression<? extends N> x, public <N extends Number> Expression<N> prod(Expression<? extends N> x, N y) {
N y) {
return new Expressions.Product<N>(x,y); return new Expressions.Product<N>(x,y);
} }
public <N extends Number> Expression<N> prod(N x, public <N extends Number> Expression<N> prod(N x, Expression<? extends N> y) {
Expression<? extends N> y) {
return new Expressions.Product<N>(x,y); return new Expressions.Product<N>(x,y);
} }
public Expression<Number> quot(Expression<? extends Number> x, public Expression<Number> quot(Expression<? extends Number> x, Expression<? extends Number> y) {
Expression<? extends Number> y) {
return new Expressions.Quotient<Number>(x,y); return new Expressions.Quotient<Number>(x,y);
} }
@ -574,17 +536,21 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Quotient<Number>(x,y); return new Expressions.Quotient<Number>(x,y);
} }
public <Y> Selection<Y> select(Class<Y> result, /**
Selection<?>... selections) { * Define a select list item corresponding to a constructor.
return new SelectionImpl(result).setSelections(selections); * @param result class whose instance is to be constructed
* @param selections arguments to the constructor
* @return selection item
*/
public <Y> Selection<Y> construct(Class<Y> result, Selection<?>... selections) {
return new NewInstanceSelection<Y>(result, selections);
} }
public <R> Case<R> selectCase() { public <R> Case<R> selectCase() {
return new Expressions.Case(); return new Expressions.Case();
} }
public <C, R> SimpleCase<C, R> selectCase( public <C, R> SimpleCase<C, R> selectCase(Expression<? extends C> expression) {
Expression<? extends C> expression) {
return new Expressions.SimpleCase(expression); return new Expressions.SimpleCase(expression);
} }
@ -592,8 +558,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Size(collection); return new Expressions.Size(collection);
} }
public <C extends Collection<?>> Expression<Integer> size( public <C extends Collection<?>> Expression<Integer> size(Expression<C> collection) {
Expression<C> collection) {
return new Expressions.Size(collection); return new Expressions.Size(collection);
} }
@ -606,8 +571,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Sqrt(x); return new Expressions.Sqrt(x);
} }
public Expression<String> substring(Expression<String> x, public Expression<String> substring(Expression<String> x, Expression<Integer> from) {
Expression<Integer> from) {
return new Expressions.Substring(x, from); return new Expressions.Substring(x, from);
} }
@ -615,13 +579,11 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Substring(x, from); return new Expressions.Substring(x, from);
} }
public Expression<String> substring(Expression<String> x, public Expression<String> substring(Expression<String> x, Expression<Integer> from, Expression<Integer> len) {
Expression<Integer> from, Expression<Integer> len) {
return new Expressions.Substring(x, from, len); return new Expressions.Substring(x, from, len);
} }
public Expression<String> substring(Expression<String> x, int from, public Expression<String> substring(Expression<String> x, int from, int len) {
int len) {
return new Expressions.Substring(x, from, len); return new Expressions.Substring(x, from, len);
} }
@ -629,28 +591,23 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Sum<N>(x); return new Expressions.Sum<N>(x);
} }
public <N extends Number> Expression<N> sum(Expression<? extends N> x, public <N extends Number> Expression<N> sum(Expression<? extends N> x, Expression<? extends N> y) {
Expression<? extends N> y) {
return new Expressions.Sum<N>(x,y); return new Expressions.Sum<N>(x,y);
} }
public <N extends Number> Expression<N> sum(Expression<? extends N> x, public <N extends Number> Expression<N> sum(Expression<? extends N> x, N y) {
N y) {
return new Expressions.Sum<N>(x,y); return new Expressions.Sum<N>(x,y);
} }
public <N extends Number> Expression<N> sum(N x, public <N extends Number> Expression<N> sum(N x, Expression<? extends N> y) {
Expression<? extends N> y) {
return new Expressions.Sum<N>(x,y); return new Expressions.Sum<N>(x,y);
} }
public Expression<BigDecimal> toBigDecimal( public Expression<BigDecimal> toBigDecimal(Expression<? extends Number> number) {
Expression<? extends Number> number) {
return new Expressions.Cast<BigDecimal>(number, BigDecimal.class); return new Expressions.Cast<BigDecimal>(number, BigDecimal.class);
} }
public Expression<BigInteger> toBigInteger( public Expression<BigInteger> toBigInteger(Expression<? extends Number> number) {
Expression<? extends Number> number) {
return new Expressions.Cast<BigInteger>(number, BigInteger.class); return new Expressions.Cast<BigInteger>(number, BigInteger.class);
} }
@ -682,8 +639,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Trim(x, ts); return new Expressions.Trim(x, ts);
} }
public Expression<String> trim(Expression<Character> t, public Expression<String> trim(Expression<Character> t, Expression<String> x) {
Expression<String> x) {
return new Expressions.Trim(x, t); return new Expressions.Trim(x, t);
} }
@ -691,8 +647,7 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser {
return new Expressions.Trim(x, t); return new Expressions.Trim(x, t);
} }
public Expression<String> trim(Trimspec ts, Expression<Character> t, public Expression<String> trim(Trimspec ts, Expression<Character> t, Expression<String> x) {
Expression<String> x) {
return new Expressions.Trim(x, t, ts); return new Expressions.Trim(x, t, ts);
} }

View File

@ -87,16 +87,14 @@ public class CriteriaExpressionBuilder {
Class<?> cls = join.getAttribute().getJavaType(); Class<?> cls = join.getAttribute().getJavaType();
if (join.getAttribute().isAssociation()) { if (join.getAttribute().isAssociation()) {
ClassMetaData meta = metamodel.repos.getMetaData(cls, null, true); ClassMetaData meta = metamodel.repos.getMetaData(cls, null, true);
PersistenceType type = metamodel.getPersistenceType(meta); PersistenceType type = MetamodelImpl.getPersistenceType(meta);
if (type == PersistenceType.ENTITY || type == PersistenceType.EMBEDDABLE) if (type == PersistenceType.ENTITY || type == PersistenceType.EMBEDDABLE)
metas.add(meta); metas.add(meta);
} }
} }
if (root.getFetches() != null) { if (root.getFetches() != null) {
for (Fetch<?,?> fetch : root.getFetches()) { for (Fetch<?,?> fetch : root.getFetches()) {
metas.add(metamodel.repos.getMetaData( metas.add(metamodel.repos.getMetaData(fetch.getAttribute().getJavaType(), null, false));
fetch.getAttribute().getJavaType(),
null, false));
} }
} }
} }
@ -140,12 +138,10 @@ public class CriteriaExpressionBuilder {
exps.grouping = new Value[groupByCount]; exps.grouping = new Value[groupByCount];
for (int i = 0; i < groupByCount; i++) { for (int i = 0; i < groupByCount; i++) {
Expression<?> groupBy = groups.get(i); Expression<?> groupBy = groups.get(i);
exps.grouping[i] = Expressions.toValue( exps.grouping[i] = Expressions.toValue((ExpressionImpl<?>)groupBy, factory, model, q);;
(ExpressionImpl<?>)groupBy, factory, model, q);;
} }
exps.having = having == null ? factory.emptyExpression() exps.having = having == null ? factory.emptyExpression() : having.toKernelExpression(factory, model, q);
: having.toKernelExpression(factory, model, q);
} }
protected void evalDistinct(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) { protected void evalDistinct(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
@ -170,8 +166,7 @@ public class CriteriaExpressionBuilder {
for (Root<?> root : roots) { for (Root<?> root : roots) {
if (root.getJoins() != null) { if (root.getJoins() != null) {
for (Join<?, ?> join : root.getJoins()) { for (Join<?, ?> join : root.getJoins()) {
filter = and(factory, ((ExpressionImpl<?>)join) filter = and(factory, ((ExpressionImpl<?>)join).toKernelExpression(factory, model, q), filter);
.toKernelExpression(factory, model, q), filter);
} }
} }
((RootImpl<?>)root).addToContext(factory, model, q); ((RootImpl<?>)root).addToContext(factory, model, q);
@ -181,17 +176,17 @@ public class CriteriaExpressionBuilder {
List<Join<?,?>> corrJoins = subQuery.getCorrelatedJoins(); List<Join<?,?>> corrJoins = subQuery.getCorrelatedJoins();
if (corrJoins != null) { if (corrJoins != null) {
for (int i = 0; i < corrJoins.size(); i++) for (int i = 0; i < corrJoins.size(); i++)
filter = and(factory, ((ExpressionImpl<?>)corrJoins.get(i)) filter = and(factory, ((ExpressionImpl<?>)corrJoins.get(i)).toKernelExpression(factory, model, q),
.toKernelExpression(factory, model, q), filter); filter);
} }
} }
if (where != null) { if (where != null) {
filter = and(factory, where.toKernelExpression filter = and(factory, where.toKernelExpression(factory, model, q), filter);
(factory, model, q), filter);
} }
if (filter == null) if (filter == null) {
filter = factory.emptyExpression(); filter = factory.emptyExpression();
}
exps.filter = filter; exps.filter = filter;
} }
@ -207,26 +202,22 @@ public class CriteriaExpressionBuilder {
exps.projections = new Value[selections.size()]; exps.projections = new Value[selections.size()];
List<Value> projections = new ArrayList<Value>(); List<Value> projections = new ArrayList<Value>();
List<String> aliases = new ArrayList<String>(); List<String> aliases = new ArrayList<String>();
getProjections(exps, selections, projections, aliases, factory, q, getProjections(exps, selections, projections, aliases, factory, q, model);
model); exps.projections = projections.toArray(new Value[projections.size()]);
exps.projections = projections.toArray(new Value[0]); exps.projectionAliases = aliases.toArray(new String[aliases.size()]);
exps.projectionAliases = aliases.toArray(new String[0]);
} }
private void getProjections(QueryExpressions exps, private void getProjections(QueryExpressions exps, List<Selection<?>> selections,
List<Selection<?>> selections, List projections, List<String> aliases, List<Value> projections, List<String> aliases,
ExpressionFactory factory, CriteriaQueryImpl<?> q, MetamodelImpl model) { ExpressionFactory factory, CriteriaQueryImpl<?> q, MetamodelImpl model) {
for (Selection<?> s : selections) { for (Selection<?> s : selections) {
List<Selection<?>> sels = ((SelectionImpl)s).getSelections(); if (s instanceof NewInstanceSelection<?>) {
if (sels == null) {
projections.add(((ExpressionImpl<?>)s).
toValue(factory, model, q));
aliases.add(q.getAlias(s));
} else {
// this is for constructor expression in the selection
exps.resultClass = s.getJavaType(); exps.resultClass = s.getJavaType();
getProjections(exps, sels, projections, aliases, factory, q, getProjections(exps, ((NewInstanceSelection)s).getConstructorArguments(), projections, aliases,
model); factory, q, model);
} else {
projections.add(((ExpressionImpl<?>)s).toValue(factory, model, q));
aliases.add(q.getAlias(s));
} }
} }
} }
@ -269,10 +260,8 @@ public class CriteriaExpressionBuilder {
exps.fetchPaths = oPaths.toArray(new String[oPaths.size()]); exps.fetchPaths = oPaths.toArray(new String[oPaths.size()]);
} }
protected static org.apache.openjpa.kernel.exps.Expression and ( protected static org.apache.openjpa.kernel.exps.Expression and (ExpressionFactory factory,
ExpressionFactory factory, org.apache.openjpa.kernel.exps.Expression e1, org.apache.openjpa.kernel.exps.Expression e2) {
org.apache.openjpa.kernel.exps.Expression e1,
org.apache.openjpa.kernel.exps.Expression e2) {
return e1 == null ? e2 : e2 == null ? e1 : factory.and(e1, e2); return e1 == null ? e2 : e2 == null ? e1 : factory.and(e1, e2);
} }
} }

View File

@ -71,6 +71,7 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
private List<Subquery<?>> _subqueries; private List<Subquery<?>> _subqueries;
private Boolean _distinct; private Boolean _distinct;
private SubqueryImpl<?> _delegator; private SubqueryImpl<?> _delegator;
private final Class<T> _resultClass;
// AliasContext // AliasContext
private int aliasCount = 0; private int aliasCount = 0;
@ -85,13 +86,15 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
// SubqueryContext // SubqueryContext
//private Stack<Context> _contexts = null; //private Stack<Context> _contexts = null;
public CriteriaQueryImpl(MetamodelImpl model) { public CriteriaQueryImpl(MetamodelImpl model, Class<T> resultClass) {
this._model = model; this._model = model;
this._resultClass = resultClass;
_aliases = new HashMap<Selection<?>, String>(); _aliases = new HashMap<Selection<?>, String>();
} }
public CriteriaQueryImpl(MetamodelImpl model, SubqueryImpl<?> delegator) { public CriteriaQueryImpl(MetamodelImpl model, SubqueryImpl<T> delegator) {
this._model = model; this._model = model;
this._resultClass = delegator.getJavaType();
_delegator = delegator; _delegator = delegator;
_aliases = getAliases(); _aliases = getAliases();
} }
@ -112,7 +115,7 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
// return _contexts; // return _contexts;
//} //}
public CriteriaQuery distinct(boolean distinct) { public CriteriaQuery<T> distinct(boolean distinct) {
_distinct = distinct; _distinct = distinct;
return this; return this;
} }
@ -171,7 +174,7 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
* @return the modified query * @return the modified query
*/ */
public CriteriaQuery<T> multiselect(Selection<?>... selections) { public CriteriaQuery<T> multiselect(Selection<?>... selections) {
throw new AbstractMethodError(); return select(selections);
} }
/** /**
@ -200,26 +203,26 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
return _selections; return _selections;
} }
public CriteriaQuery groupBy(Expression<?>... grouping) { public CriteriaQuery<T> groupBy(Expression<?>... grouping) {
_groups = new ArrayList<Expression<?>>(); _groups = new ArrayList<Expression<?>>();
for (Expression<?> e : grouping) for (Expression<?> e : grouping)
_groups.add(e); _groups.add(e);
return this; return this;
} }
public CriteriaQuery having(Expression<Boolean> restriction) { public CriteriaQuery<T> having(Expression<Boolean> restriction) {
_having = new PredicateImpl().add(restriction); _having = new PredicateImpl().add(restriction);
return this; return this;
} }
public CriteriaQuery having(Predicate... restrictions) { public CriteriaQuery<T> having(Predicate... restrictions) {
_having = new PredicateImpl(); _having = new PredicateImpl();
for (Predicate p : restrictions) for (Predicate p : restrictions)
_having.add(p); _having.add(p);
return this; return this;
} }
public CriteriaQuery orderBy(Order... o) { public CriteriaQuery<T> orderBy(Order... o) {
_orders = Arrays.asList(o); _orders = Arrays.asList(o);
return this; return this;
} }
@ -232,7 +235,7 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
* @return the modified query * @return the modified query
*/ */
public CriteriaQuery<T> select(Selection<T> selection) { public CriteriaQuery<T> select(Selection<T> selection) {
throw new AbstractMethodError(); return select(new Selection<?>[]{selection});
} }
public CriteriaQuery<T> select(Selection<?>... selections) { public CriteriaQuery<T> select(Selection<?>... selections) {
@ -348,18 +351,18 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
// _contexts = contexts; // _contexts = contexts;
//} //}
public CriteriaQueryImpl getInnermostParent() { public CriteriaQueryImpl<?> getInnermostParent() {
if (_delegator == null) if (_delegator == null)
return this; return this;
AbstractQuery parent = _delegator.getParent(); AbstractQuery<?> parent = _delegator.getParent();
if (parent instanceof CriteriaQueryImpl) if (parent instanceof CriteriaQueryImpl)
return (CriteriaQueryImpl)parent; return (CriteriaQueryImpl<?>)parent;
// parent is a SubqueryImpl // parent is a SubqueryImpl
return ((SubqueryImpl)parent).getDelegate().getInnermostParent(); return ((SubqueryImpl<?>)parent).getDelegate().getInnermostParent();
} }
public Map<Selection<?>,String> getAliases() { public Map<Selection<?>,String> getAliases() {
CriteriaQueryImpl c = getInnermostParent(); CriteriaQueryImpl<?> c = getInnermostParent();
if (c._aliases == null) if (c._aliases == null)
c._aliases = new HashMap<Selection<?>, String>(); c._aliases = new HashMap<Selection<?>, String>();
return c._aliases; return c._aliases;

View File

@ -27,6 +27,7 @@ import javax.persistence.criteria.QueryBuilder.In;
import org.apache.openjpa.kernel.exps.ExpressionFactory; import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Value; import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.persistence.ResultItemImpl;
import org.apache.openjpa.persistence.meta.MetamodelImpl; import org.apache.openjpa.persistence.meta.MetamodelImpl;
/** /**
@ -36,13 +37,14 @@ import org.apache.openjpa.persistence.meta.MetamodelImpl;
* *
* @param <X> the type of the value this expression represents. * @param <X> the type of the value this expression represents.
*/ */
public class ExpressionImpl<X> extends SelectionImpl<X> public abstract class ExpressionImpl<X> extends ResultItemImpl<X>
implements Expression<X> { implements Expression<X> {
Value toValue(ExpressionFactory factory, MetamodelImpl model, abstract Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) { CriteriaQueryImpl<?> q);
throw new AbstractMethodError(this.getClass().getName()); // {
} // throw new AbstractMethodError(this.getClass().getName());
// }
org.apache.openjpa.kernel.exps.Expression toKernelExpression( org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, ExpressionFactory factory, MetamodelImpl model,
@ -65,7 +67,7 @@ public class ExpressionImpl<X> extends SelectionImpl<X>
* @return expression * @return expression
*/ */
public <Y> Expression<Y> as(Class<Y> type) { public <Y> Expression<Y> as(Class<Y> type) {
throw new AbstractMethodError(); return new Expressions.CastAs<Y>(type, this);
} }
/** /**

View File

@ -62,7 +62,7 @@ public class Expressions {
* *
* @param <X> the type of the resultant expression * @param <X> the type of the resultant expression
*/ */
public static class UnaryFunctionalExpression<X> public abstract static class UnaryFunctionalExpression<X>
extends ExpressionImpl<X> { extends ExpressionImpl<X> {
protected ExpressionImpl<?> e; protected ExpressionImpl<?> e;
@ -83,7 +83,7 @@ public class Expressions {
* *
* @param <X> the type of the resultant expression * @param <X> the type of the resultant expression
*/ */
public static class BinarayFunctionalExpression<X> public abstract static class BinarayFunctionalExpression<X>
extends ExpressionImpl<X>{ extends ExpressionImpl<X>{
protected ExpressionImpl<?> e1; protected ExpressionImpl<?> e1;
protected ExpressionImpl<?> e2; protected ExpressionImpl<?> e2;
@ -241,6 +241,7 @@ public class Expressions {
return factory.cast(Expressions.toValue(e, factory, model, q), b); return factory.cast(Expressions.toValue(e, factory, model, q), b);
} }
} }
public static class Concat extends BinarayFunctionalExpression<String> { public static class Concat extends BinarayFunctionalExpression<String> {
public Concat(Expression<String> x, Expression<String> y) { public Concat(Expression<String> x, Expression<String> y) {
super(String.class, x, y); super(String.class, x, y);
@ -758,6 +759,29 @@ public class Expressions {
} }
} }
public static class IsNotEmpty extends PredicateImpl {
ExpressionImpl<?> collection;
public IsNotEmpty(Expression<?> collection) {
super();
this.collection = (ExpressionImpl<?>)collection;
}
@Override
public PredicateImpl clone() {
return new IsNotEmpty(collection);
}
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
Value val = Expressions.toValue(collection, factory, model, q);
return (isNegated())
? factory.isEmpty(val) : factory.isNotEmpty(val);
}
}
public static class Index extends UnaryFunctionalExpression<Integer> { public static class Index extends UnaryFunctionalExpression<Integer> {
public Index(Joins.List<?,?> e) { public Index(Joins.List<?,?> e) {
super(Integer.class, e); super(Integer.class, e);
@ -1263,4 +1287,20 @@ public class Expressions {
} }
} }
public static class CastAs<Y> extends ExpressionImpl<Y> {
protected final ExpressionImpl<?> actual;
public CastAs(Class<Y> cast, ExpressionImpl<?> actual) {
super(cast);
this.actual = actual;
}
@Override
public org.apache.openjpa.kernel.exps.Value toValue(
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
org.apache.openjpa.kernel.exps.Value e = actual.toValue(factory, model, q);
e.setImplicitType(getJavaType());
return e;
}
}
} }

View File

@ -47,8 +47,7 @@ public class FetchPathImpl<Z,X> extends PathImpl<Z,X> implements Fetch<Z, X> {
this(parent, member, JoinType.INNER); this(parent, member, JoinType.INNER);
} }
FetchPathImpl(FetchParent<?,Z> parent, Members.Member<? super Z,X> member, FetchPathImpl(FetchParent<?,Z> parent, Members.Member<? super Z,X> member, JoinType type) {
JoinType type) {
super((PathImpl<?,Z>)parent, member, member.getJavaType()); super((PathImpl<?,Z>)parent, member, member.getJavaType());
this.joinType = type; this.joinType = type;
} }

View File

@ -38,6 +38,7 @@ import javax.persistence.metamodel.SetAttribute;
import org.apache.openjpa.kernel.exps.ExpressionFactory; import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Value; import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.persistence.meta.Members; import org.apache.openjpa.persistence.meta.Members;
import org.apache.openjpa.persistence.meta.MetamodelImpl; import org.apache.openjpa.persistence.meta.MetamodelImpl;
import org.apache.openjpa.persistence.meta.Members.Member; import org.apache.openjpa.persistence.meta.Members.Member;
@ -56,7 +57,7 @@ public abstract class Joins {
* @param <Z> type from which joining * @param <Z> type from which joining
* @param <X> type of the attribute being joined * @param <X> type of the attribute being joined
*/ */
public static class SingularJoin<Z,X> extends FromImpl<Z,X> implements Join<Z,X>{ public static class SingularJoin<Z,X> extends FromImpl<Z,X> implements Join<Z,X> {
private final JoinType joinType; private final JoinType joinType;
private boolean allowNull = false; private boolean allowNull = false;
@ -448,11 +449,7 @@ public abstract class Joins {
MetamodelImpl model, CriteriaQueryImpl<?> c) { MetamodelImpl model, CriteriaQueryImpl<?> c) {
org.apache.openjpa.kernel.exps.Value path = toValue(factory, model, c); org.apache.openjpa.kernel.exps.Value path = toValue(factory, model, c);
ClassMetaData meta = _member.fmd.isElementCollection() Value var = factory.newBoundVariable(c.getAlias(this), _member.fmd.getElement().getDeclaredType());
? _member.fmd.getEmbeddedMetaData()
: _member.fmd.getElement().getDeclaredTypeMetaData();
Value var = factory.newBoundVariable(c.getAlias(this), meta.getDescribedType());
org.apache.openjpa.kernel.exps.Expression join = factory.bindValueVariable(var, path); org.apache.openjpa.kernel.exps.Expression join = factory.bindValueVariable(var, path);
c.registerVariable(this, var, path); c.registerVariable(this, var, path);
return join; return join;

View File

@ -0,0 +1,49 @@
/*
* 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 java.util.Arrays;
import java.util.List;
import javax.persistence.criteria.Selection;
import org.apache.openjpa.persistence.ResultItemImpl;
/**
* A selection item that constructs new instance of a user-defined class with arguments specified as other selected
* items.
*
* @author Pinaki Poddar
*
* @param <X>
*/
public class NewInstanceSelection<X> extends ResultItemImpl<X>
implements Selection<X> {
private List<Selection<?>> _args;
public NewInstanceSelection(Class<X> cls, Selection<?>... selections) {
super(cls);
_args = Arrays.asList(selections);
}
public List<Selection<?>> getConstructorArguments() {
return _args;
}
}

View File

@ -36,7 +36,7 @@ import org.apache.openjpa.persistence.meta.MetamodelImpl;
* *
* @param <T> the type of value held by this parameter. * @param <T> the type of value held by this parameter.
*/ */
public class ParameterImpl<T> extends ExpressionImpl<T> implements ParameterExpression<T>{ public class ParameterImpl<T> extends ExpressionImpl<T> implements ParameterExpression<T> {
private String name; private String name;
private Integer position; private Integer position;
@ -58,11 +58,9 @@ public class ParameterImpl<T> extends ExpressionImpl<T> implements ParameterExpr
} }
@Override @Override
public Value toValue(ExpressionFactory factory, MetamodelImpl model, public Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
CriteriaQueryImpl<?> q) {
q.registerParameter(this); q.registerParameter(this);
ClassMetaData meta = null; ClassMetaData meta = null;
Class<?> clzz = getJavaType(); Class<?> clzz = getJavaType();
Object paramKey = getKey(); Object paramKey = getKey();

View File

@ -29,6 +29,7 @@ import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute; import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type; import javax.persistence.metamodel.Type;
import javax.persistence.metamodel.Type.PersistenceType;
import org.apache.openjpa.kernel.exps.ExpressionFactory; import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Value; import org.apache.openjpa.kernel.exps.Value;
@ -43,8 +44,9 @@ import org.apache.openjpa.persistence.meta.MetamodelImpl;
* @param <X> Type referenced by the path * @param <X> Type referenced by the path
*/ */
/** /**
* Path is an expression often representing a persistent member traversed * Path is an expression often representing a persistent attribute traversed from another (parent) path.
* from another (parent) path. * The type of the path is the type of the persistent attribute.
* If the persistent attribute is bindable, then further path can be travesered from this path.
* *
* @author Pinaki Poddar * @author Pinaki Poddar
* @author Fay Wang * @author Fay Wang
@ -59,8 +61,7 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
protected PathImpl<?,?> _correlatedPath; protected PathImpl<?,?> _correlatedPath;
/** /**
* Protected. use by root path which neither represent a member nor has a * Protected constructor use by root path which neither represent a member nor has a parent.
* parent.
*/ */
protected PathImpl(Class<X> cls) { protected PathImpl(Class<X> cls) {
super(cls); super(cls);
@ -69,12 +70,10 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
} }
/** /**
* Create a path from the given non-null parent representing the the given * Create a path from the given non-null parent representing the given non-null member. The given class denotes
* non-null member. The given class denotes the type expressed by this * the type expressed by this path.
* path.
*/ */
public PathImpl(PathImpl<?,Z> parent, Members.Member<? super Z, ?> member, public PathImpl(PathImpl<?,Z> parent, Members.Member<? super Z, ?> member, Class<X> cls) {
Class<X> cls) {
super(cls); super(cls);
_parent = parent; _parent = parent;
if (_parent.isEmbedded) { if (_parent.isEmbedded) {
@ -91,6 +90,9 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
* *
*/ */
public Bindable<X> getModel() { public Bindable<X> getModel() {
if (_member instanceof Bindable<?> == false) {
throw new IllegalArgumentException(this + " represents a basic path and not a bindable");
}
return (Bindable<X>)_member; return (Bindable<X>)_member;
} }
@ -101,6 +103,9 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
return _parent; return _parent;
} }
/**
* Gets the path that originates this traversal. Can be itself if this itself is the origin.
*/
public PathImpl<?,?> getInnermostParentPath() { public PathImpl<?,?> getInnermostParentPath() {
return (_parent == null) ? this : _parent.getInnermostParentPath(); return (_parent == null) ? this : _parent.getInnermostParentPath();
} }
@ -115,13 +120,13 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
} }
protected Members.Member<?,?> getInnermostMember(PathImpl<?,?> parent, Members.Member<?,?> member) { protected Members.Member<?,?> getInnermostMember(PathImpl<?,?> parent, Members.Member<?,?> member) {
return member != null ? member : getInnermostMember(parent._parent, return member != null ? member : getInnermostMember(parent._parent, parent._member);
parent._member);
} }
public void setCorrelatedPath(PathImpl<?,?> correlatedPath) { public void setCorrelatedPath(PathImpl<?,?> correlatedPath) {
_correlatedPath = correlatedPath; _correlatedPath = correlatedPath;
} }
public PathImpl<?,?> getCorrelatedPath() { public PathImpl<?,?> getCorrelatedPath() {
return _correlatedPath; return _correlatedPath;
} }
@ -130,8 +135,7 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
* Convert this path to a kernel path. * Convert this path to a kernel path.
*/ */
@Override @Override
public Value toValue( public Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
if (q.isRegistered(this)) if (q.isRegistered(this))
return q.getValue(this); return q.getValue(this);
org.apache.openjpa.kernel.exps.Path path = null; org.apache.openjpa.kernel.exps.Path path = null;
@ -151,8 +155,7 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
//path.setSchemaAlias(q.getAlias(_parent)); //path.setSchemaAlias(q.getAlias(_parent));
traversePath(_parent, path, _member.fmd); traversePath(_parent, path, _member.fmd);
} else if (_parent != null) { } else if (_parent != null) {
path = (org.apache.openjpa.kernel.exps.Path) path = (org.apache.openjpa.kernel.exps.Path)_parent.toValue(factory, model, q);
_parent.toValue(factory, model, q);
path.get(_member.fmd, allowNull); path.get(_member.fmd, allowNull);
} else if (_parent == null) { } else if (_parent == null) {
path = factory.newPath(); path = factory.newPath();
@ -206,48 +209,41 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
} }
/** /**
* Return the path corresponding to the referenced * Gets a new path that represents the given single-valued attribute from this path.
* single-valued attribute.
* @param atttribute single-valued attribute
* @return path corresponding to the referenced attribute
*/
/**
* Create a new path with this path as parent.
*/ */
public <Y> Path<Y> get(SingularAttribute<? super X, Y> attr) { public <Y> Path<Y> get(SingularAttribute<? super X, Y> attr) {
return new PathImpl<X,Y>(this, (Members.SingularAttributeImpl<? super X, Y>)attr, return new PathImpl<X,Y>(this, (Members.SingularAttributeImpl<? super X, Y>)attr, attr.getJavaType());
attr.getJavaType());
} }
/** /**
* Return the path corresponding to the referenced * Gets a new path that represents the given multi-valued attribute from this path.
* collection-valued attribute.
* @param collection collection-valued attribute
* @return expression corresponding to the referenced attribute
*/ */
public <E, C extends java.util.Collection<E>> Expression<C> get(PluralAttribute<X, C, E> coll) { public <E, C extends java.util.Collection<E>> Expression<C> get(PluralAttribute<X, C, E> coll) {
return new PathImpl<X,C>(this, (Members.Member<? super X, C>)coll, coll.getJavaType()); return new PathImpl<X,C>(this, (Members.PluralAttributeImpl<? super X, C, E>)coll, coll.getJavaType());
} }
/** /**
* Return the path corresponding to the referenced * Gets a new path that represents the given map-valued attribute from this path.
* map-valued attribute.
* @param map map-valued attribute
* @return expression corresponding to the referenced attribute
*/ */
public <K, V, M extends java.util.Map<K, V>> Expression<M> get(MapAttribute<X, K, V> map) { public <K, V, M extends java.util.Map<K, V>> Expression<M> get(MapAttribute<X, K, V> map) {
return new PathImpl<X,M>(this, (Members.MapAttributeImpl<? super X,K,V>)map, (Class<M>)map.getJavaType()); return new PathImpl<X,M>(this, (Members.MapAttributeImpl<? super X,K,V>)map, (Class<M>)map.getJavaType());
} }
/**
* Gets a new path that represents the attribute of the given name from this path.
*
* @exception IllegalArgumentException if this path represents a basic attribute that is can not be traversed
* further.
*/
public <Y> Path<Y> get(String attName) { public <Y> Path<Y> get(String attName) {
Members.Member<? super X, Y> next = null;
Type<?> type = _member.getType(); Type<?> type = _member.getType();
switch (type.getPersistenceType()) { if (type.getPersistenceType() == PersistenceType.BASIC) {
case BASIC: throw new IllegalArgumentException(this + " is a basic path and can not be navigated to " + attName);
throw new RuntimeException(attName + " not navigable from " + this);
default: next = (Members.Member<? super X, Y>) ((ManagedType<?>)type).getAttribute(attName);
} }
return new PathImpl<X,Y>(this, next, (Class<Y>)type.getClass());
Members.Member<? super X, Y> next = (Members.Member<? super X, Y>)
((ManagedType<? super X>)type).getAttribute(attName);
return new PathImpl<X,Y>(this, next, next.getJavaType());
} }
/** /**
@ -255,5 +251,5 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
*/ */
public Expression<Class<? extends X>> type() { public Expression<Class<? extends X>> type() {
return new Expressions.Type<X>(this); return new Expressions.Type<X>(this);
} }
} }

View File

@ -27,10 +27,9 @@ import javax.persistence.criteria.Predicate;
import org.apache.openjpa.kernel.exps.ExpressionFactory; import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.persistence.meta.MetamodelImpl; import org.apache.openjpa.persistence.meta.MetamodelImpl;
public class PredicateImpl extends ExpressionImpl<Boolean> public class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate {
implements Predicate {
List<Expression<Boolean>> _exps; List<Expression<Boolean>> _exps;
BooleanOperator _op; BooleanOperator _op = BooleanOperator.AND;
boolean _negated = false; boolean _negated = false;
protected PredicateImpl() { protected PredicateImpl() {
@ -83,31 +82,34 @@ implements Predicate {
} }
@Override @Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression( org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, MetamodelImpl model,
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
throw new AbstractMethodError();
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) { CriteriaQueryImpl<?> q) {
if (_exps == null || _exps.isEmpty()) if (_exps == null || _exps.isEmpty())
return factory.emptyExpression(); return factory.emptyExpression();
if (_exps.size() == 1) if (_exps.size() == 1)
return ((ExpressionImpl<?>)_exps.get(0)) return ((ExpressionImpl<?>)_exps.get(0)).toKernelExpression(factory, model, q);
.toKernelExpression(factory, model, q);
ExpressionImpl<?> e1 = (ExpressionImpl<?>)_exps.get(0); ExpressionImpl<?> e1 = (ExpressionImpl<?>)_exps.get(0);
ExpressionImpl<?> e2 = (ExpressionImpl<?>)_exps.get(1); ExpressionImpl<?> e2 = (ExpressionImpl<?>)_exps.get(1);
org.apache.openjpa.kernel.exps.Expression ke1 = org.apache.openjpa.kernel.exps.Expression ke1 = e1.toKernelExpression(factory, model, q);
e1.toKernelExpression(factory, model, q); org.apache.openjpa.kernel.exps.Expression ke2 = e2.toKernelExpression(factory, model, q);
org.apache.openjpa.kernel.exps.Expression ke2 = org.apache.openjpa.kernel.exps.Expression result = _op == BooleanOperator.AND
e2.toKernelExpression(factory, model, q);
org.apache.openjpa.kernel.exps.Expression result =
_op == BooleanOperator.AND
? factory.and(ke1,ke2) : factory.or(ke1, ke2); ? factory.and(ke1,ke2) : factory.or(ke1, ke2);
for (int i = 2; i < _exps.size(); i++) { for (int i = 2; i < _exps.size(); i++) {
ExpressionImpl<?> e = (ExpressionImpl<?>)_exps.get(i); ExpressionImpl<?> e = (ExpressionImpl<?>)_exps.get(i);
result = _op == BooleanOperator.AND result = _op == BooleanOperator.AND
? factory.and(result, e.toKernelExpression(factory, model, q)) ? factory.and(result, e.toKernelExpression(factory, model, q))
: factory.or(result, e.toKernelExpression(factory,model,q)); : factory.or(result, e.toKernelExpression(factory,model,q));
} }
return _negated ? factory.not(result) : result; return _negated ? factory.not(result) : result;
} }
public static class And extends PredicateImpl { public static class And extends PredicateImpl {

View File

@ -41,12 +41,12 @@ public class SelectionImpl<X> extends ResultItemImpl<X>
super(cls); super(cls);
} }
public SelectionImpl<X> setSelections(Selection<?>... selections) { // public SelectionImpl<X> setSelections(Selection<?>... selections) {
_sels = Arrays.asList(selections); // _sels = Arrays.asList(selections);
return this; // return this;
} // }
//
public List<Selection<?>> getSelections() { // public List<Selection<?>> getSelections() {
return _sels; // return _sels;
} // }
} }

View File

@ -41,7 +41,6 @@ import org.apache.openjpa.kernel.exps.QueryExpressions;
import org.apache.openjpa.kernel.exps.Value; import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder; import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder;
import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes; import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.persistence.meta.AbstractManagedType; import org.apache.openjpa.persistence.meta.AbstractManagedType;
import org.apache.openjpa.persistence.meta.Members; import org.apache.openjpa.persistence.meta.Members;

View File

@ -38,6 +38,7 @@ import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.PluralAttribute.CollectionType; import javax.persistence.metamodel.PluralAttribute.CollectionType;
import org.apache.openjpa.kernel.Filters;
import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData; import org.apache.openjpa.meta.FieldMetaData;
@ -850,8 +851,7 @@ public abstract class AbstractManagedType<X> extends Types.BaseType<X>
* Selects if the attribute type matches the given Java class. * Selects if the attribute type matches the given Java class.
* null matches any type. * null matches any type.
*/ */
public static final class AttributeTypeFilter<X, Y> implements public static final class AttributeTypeFilter<X, Y> implements Filter<Attribute<? super X, ?>> {
Filter<Attribute<? super X, ?>> {
private final Class<Y> _type; private final Class<Y> _type;
private final boolean _invert; private final boolean _invert;
@ -865,7 +865,7 @@ public abstract class AbstractManagedType<X> extends Types.BaseType<X>
} }
public boolean selects(Attribute<? super X, ?> attr) { public boolean selects(Attribute<? super X, ?> attr) {
boolean result = _type == null || attr.getJavaType() == _type; boolean result = _type == null || Filters.canConvert(attr.getJavaType(), _type, false);
return _invert ? !result : result; return _invert ? !result : result;
} }

View File

@ -98,8 +98,7 @@ public class AnnotationProcessor6 extends AbstractProcessor {
private int generatedSourceVersion = 6; private int generatedSourceVersion = 6;
private CompileTimeLogger logger; private CompileTimeLogger logger;
private boolean addHeader = false; private boolean addHeader = false;
private static Localizer _loc = private static Localizer _loc = Localizer.forPackage(AnnotationProcessor6.class);
Localizer.forPackage(AnnotationProcessor6.class);
/** /**
* Category of members as per JPA 2.0 type system. * Category of members as per JPA 2.0 type system.
@ -181,13 +180,12 @@ public class AnnotationProcessor6 extends AbstractProcessor {
setSourceVersion(); setSourceVersion();
setFileManager(); setFileManager();
setNamingPolicy(); setNamingPolicy();
addHeader = "true".equalsIgnoreCase(processingEnv.getOptions() addHeader = "true".equalsIgnoreCase(processingEnv.getOptions().get("header"));
.get("header"));
handler = new SourceAnnotationHandler(processingEnv, logger); handler = new SourceAnnotationHandler(processingEnv, logger);
} }
/** /**
* The entry point for javac compiler. * The entry point for java compiler.
*/ */
@Override @Override
public boolean process(Set<? extends TypeElement> annos, public boolean process(Set<? extends TypeElement> annos,

View File

@ -370,9 +370,10 @@ public class SourceAnnotationHandler
*/ */
static class TransientFilter implements InclusiveFilter<Element> { static class TransientFilter implements InclusiveFilter<Element> {
public boolean includes(Element obj) { public boolean includes(Element obj) {
Set<Modifier> modifiers = obj.getModifiers();
boolean isTransient = isAnnotatedWith(obj, Transient.class) boolean isTransient = isAnnotatedWith(obj, Transient.class)
|| obj.getModifiers().contains(Modifier.TRANSIENT); || modifiers.contains(Modifier.TRANSIENT);
return !isTransient; return !isTransient && !modifiers.contains(Modifier.STATIC);
} }
} }