Return-Path: Delivered-To: apmail-openjpa-commits-archive@www.apache.org Received: (qmail 79530 invoked from network); 26 Aug 2009 18:54:59 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 26 Aug 2009 18:54:59 -0000 Received: (qmail 12748 invoked by uid 500); 26 Aug 2009 18:54:59 -0000 Delivered-To: apmail-openjpa-commits-archive@openjpa.apache.org Received: (qmail 12695 invoked by uid 500); 26 Aug 2009 18:54:59 -0000 Mailing-List: contact commits-help@openjpa.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@openjpa.apache.org Delivered-To: mailing list commits@openjpa.apache.org Received: (qmail 12686 invoked by uid 99); 26 Aug 2009 18:54:59 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Aug 2009 18:54:59 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Aug 2009 18:54:52 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id D147D23888D6; Wed, 26 Aug 2009 18:54:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r808158 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/ openjpa-persistence/src/main/java/org/apache/openjpa/persistence/ openjpa-p... Date: Wed, 26 Aug 2009 18:54:31 -0000 To: commits@openjpa.apache.org From: ppoddar@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090826185431.D147D23888D6@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: ppoddar Date: Wed Aug 26 18:54:30 2009 New Revision: 808158 URL: http://svn.apache.org/viewvc?rev=808158&view=rev Log: OPENJPA-1265: Support edit of Criteria Query. Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEdit.java (with props) openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/criteria/ openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/criteria/localizer.properties (with props) Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestJoinCondition.java openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestMetaModelTypesafeCriteria.java openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original) +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Wed Aug 26 18:54:30 2009 @@ -3138,7 +3138,7 @@ _fm = store; pc.pcProvideField(field); // Retaining original FM because of the possibility of reentrant calls - _fm = beforeFM; + if (beforeFM != null) _fm = beforeFM; } /** @@ -3150,7 +3150,7 @@ _fm = load; pc.pcReplaceField(field); // Retaining original FM because of the possibility of reentrant calls - _fm = beforeFM; + if (beforeFM != null) _fm = beforeFM; } /** Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEdit.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEdit.java?rev=808158&view=auto ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEdit.java (added) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEdit.java Wed Aug 26 18:54:30 2009 @@ -0,0 +1,209 @@ +/* + * 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.Date; +import java.util.List; + +import javax.persistence.Tuple; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Expression; +import javax.persistence.criteria.Order; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import javax.persistence.criteria.Selection; + +/** + * Test editing of Criteria Query. + * + * The tests construct a CriteriaQuery and takes a pair of JPQL String. + * The Criteria Query is executed and its target SQL is compared with that of the first of the JPQL String pair. + * Then the same Criteria Query is edited and the target SQL of the edited version is compared with that of the second + * of the JPQL String pair. + * + * Also test boundary cases where nothing is selected etc. + * + * @author Pinaki Poddar + * + */ +public class TestEdit extends CriteriaTest { + + public void testWhereConditionEditedToAddOr() { + String jpql = "select p from Person p where p.name='XYZ'"; + String editedjpql = "select p from Person p where p.name='XYZ' or p.name='ABC'"; + + CriteriaQuery c = cb.createQuery(Person.class); + Root p = c.from(Person.class); + c.where(cb.equal(p.get(Person_.name), "XYZ")); + + assertEquivalence(c, jpql); + + Predicate where = c.getRestriction(); + c.where(cb.or(where, cb.equal(p.get(Person_.name), "ABC"))); + + assertEquivalence(c, editedjpql); + } + + public void testWhereConditionEditedToAddAnd() { + String jpql = "select p from Person p where p.name='XYZ'"; + String editedjpql = "select p from Person p where p.name='XYZ' and p.name='ABC'"; + + CriteriaQuery c = cb.createQuery(Person.class); + Root p = c.from(Person.class); + c.where(cb.equal(p.get(Person_.name), "XYZ")); + + assertEquivalence(c, jpql); + + Predicate where = c.getRestriction(); + c.where(cb.and(where, cb.equal(p.get(Person_.name), "ABC"))); + + assertEquivalence(c, editedjpql); + } + + public void testWhereConditionEditedToRemoveAnd() { + String jpql = "select p from Person p where p.name='XYZ' and p.name='ABC'"; + String editedjpql = "select p from Person p where p.name='XYZ'"; + + CriteriaQuery c = cb.createQuery(Person.class); + Root p = c.from(Person.class); + Predicate p1 = cb.equal(p.get(Person_.name), "XYZ"); + Predicate p2 = cb.equal(p.get(Person_.name), "ABC"); + c.where(p1,p2); + + assertEquivalence(c, jpql); + + Predicate where = c.getRestriction(); + List> exprs = where.getExpressions(); + assertEquals(2, exprs.size()); + assertTrue(exprs.contains(p1)); + assertTrue(exprs.contains(p2)); + exprs.remove(p1); + // editing from the list does not impact the query + assertEquivalence(c, jpql); + + c.where(p1); + assertEquivalence(c, editedjpql); + } + + public void testEditOrderBy() { + String jpql = "select p from Person p ORDER BY p.name"; + String editedjpql = "select p from Person p ORDER BY p.name, p.id DESC"; + + CriteriaQuery c = cb.createQuery(Person.class); + Root p = c.from(Person.class); + c.orderBy(cb.asc(p.get(Person_.name))); + + assertEquivalence(c, jpql); + + List orders = c.getOrderList(); + assertEquals(1, orders.size()); + orders.add(cb.desc(p.get(Person_.id))); + // editing the list does not impact query + assertEquivalence(c, jpql); + + // adding the modified list back does + c.orderBy(orders.toArray(new Order[orders.size()])); + + assertEquivalence(c, editedjpql); + } + + public void testEditedToAddMultiselectionTerm() { + String jpql = "select p from Person p"; + String editedjpql = "select p,p.name from Person p"; + + CriteriaQuery c = cb.createTupleQuery(); + Root p = c.from(Person.class); + c.multiselect(p); + + assertEquivalence(c, jpql); + + List> terms = c.getSelection().getCompoundSelectionItems(); + terms.add(p.get(Person_.name)); + // editing the list does not impact query + assertEquivalence(c, jpql); + + c.multiselect(p, p.get(Person_.name)); + assertEquivalence(c, editedjpql); + } + + public void testSingleSelectionHasNoCompoundItems() { + CriteriaQuery c = cb.createQuery(Person.class); + Root p = c.from(Person.class); + c.select(p); + try { + Selection term = c.getSelection(); + term.getCompoundSelectionItems(); + fail("Expected to fail because primary selection has no compound terms"); + } catch (IllegalStateException e) { + // good + } + } + + /** + * Candidate class is implicitly selected but a null is returned by getSelection() + */ + public void testCandidateClassIsImplicitlySelectedForEntityQuery() { + String jpql = "select p from Person p"; + CriteriaQuery c = cb.createQuery(Person.class); + Root p = c.from(Person.class); + Selection term = c.getSelection(); + assertNull(term); + + assertEquivalence(c, jpql); + } + + public void testCandidateClassIsNotImplicitlySelectedForNonEntityQuery() { + String jpql = "select p from Person p"; + CriteriaQuery c = cb.createTupleQuery(); + Root p = c.from(Person.class); + Selection term = c.getSelection(); + assertNull(term); + + assertFails("Expected to fail without a projection term", c); + } + + public void testRootIsNotImplicitlyDefined() { + CriteriaQuery c = cb.createQuery(Person.class); + Selection term = c.getSelection(); + assertNull(term); + + assertFails("Expected to fail without a defined root", c); + } + +// public void testDateString() { +// String jpql = "select d from Dependent d where d.endDate >= {d '2009-08-25'}"; +// CriteriaQuery c = cb.createQuery(Dependent.class); +// Root d = c.from(Dependent.class); +// +// c.where(cb.greaterThanOrEqualTo(d.get(Dependent_.endDate), cb.literal("{d '2009-08-25'}").as(Date.class))); +// +// assertEquivalence(c, jpql); +// } + + + void assertFails(String message, CriteriaQuery c) { + try { + em.createQuery(c); + fail(message); + } catch (IllegalStateException e) { + // good + } + } + +} Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestEdit.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestJoinCondition.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestJoinCondition.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestJoinCondition.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestJoinCondition.java Wed Aug 26 18:54:30 2009 @@ -66,7 +66,7 @@ public void testInnerJoinSingleAttributeWithoutCondition() { String jpql = "select a from A a INNER JOIN a.b b"; - CriteriaQuery c = cb.createQuery(); + CriteriaQuery c = cb.createQuery(A.class); c.from(A.class).join(A_.b, JoinType.INNER); assertEquivalence(c, jpql); @@ -74,10 +74,10 @@ public void testCrossJoinWithoutCondition() { String jpql = "select a from A a, C c"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(A.class); Root a = cq.from(A.class); Root c = cq.from(C.class); - + cq.select(a); assertEquivalence(cq, jpql); } @@ -93,17 +93,17 @@ public void testCrossJoin() { String jpql = "select a from A a, C c where a.name=c.name"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(A.class); Root a = cq.from(A.class); Root c = cq.from(C.class); cq.where(cb.equal(a.get(A_.name), c.get(C_.name))); - + cq.select(a); assertEquivalence(cq, jpql); } public void testInnerJoinSingleAttribute() { String jpql = "select a from A a INNER JOIN a.b b WHERE a.id=b.age"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(A.class); Root a = cq.from(A.class); Join b = a.join(A_.b); cq.where(cb.equal(a.get(A_.id), b.get(B_.age))); @@ -113,7 +113,7 @@ public void testOuterJoinSingleAttributeWithoutCondition() { String jpql = "select a from A a LEFT JOIN a.b b"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(A.class); Root a = cq.from(A.class); Join b = a.join(A_.b, JoinType.LEFT); @@ -122,7 +122,7 @@ public void testOuterJoinSingleAttribute() { String jpql = "select a from A a LEFT JOIN a.b b where a.id=b.age"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(A.class); Root a = cq.from(A.class); Join b = a.join(A_.b, JoinType.LEFT); cq.where(cb.equal(a.get(A_.id), b.get(B_.age))); @@ -132,7 +132,7 @@ public void testSetJoinWithoutCondition() { String jpql = "select c from C c JOIN c.set d"; - CriteriaQuery c = cb.createQuery(); + CriteriaQuery c = cb.createQuery(C.class); c.from(C.class).join(C_.set); assertEquivalence(c, jpql); @@ -140,7 +140,7 @@ public void testListJoinWithoutCondition() { String jpql = "select c from C c JOIN c.list d"; - CriteriaQuery c = cb.createQuery(); + CriteriaQuery c = cb.createQuery(C.class); c.from(C.class).join(C_.list); assertEquivalence(c, jpql); @@ -148,7 +148,7 @@ public void testCollectionJoinWithoutCondition() { String jpql = "select c from C c JOIN c.coll d"; - CriteriaQuery c = cb.createQuery(); + CriteriaQuery c = cb.createQuery(C.class); c.from(C.class).join(C_.coll); assertEquivalence(c, jpql); @@ -156,7 +156,7 @@ public void testMapJoinWithoutCondition() { String jpql = "select c from C c JOIN c.map d"; - CriteriaQuery c = cb.createQuery(); + CriteriaQuery c = cb.createQuery(C.class); c.from(C.class).join(C_.map); assertEquivalence(c, jpql); @@ -164,7 +164,7 @@ public void testKeyExpression() { String jpql = "select c from C c JOIN c.map d where KEY(d)=33"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(C.class); Root c = cq.from(C.class); MapJoin d = c.join(C_.map); cq.where(cb.equal(d.key(),33)); @@ -174,7 +174,7 @@ public void testValueExpression() { String jpql = "select c from C c JOIN c.map d where VALUE(d).name='xy'"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(C.class); Root c = cq.from(C.class); MapJoin d = c.join(C_.map); cq.where(cb.equal(d.value().get(D_.name),"xy")); @@ -185,7 +185,7 @@ public void testFetchJoin() { String jpql = "select a from A a JOIN FETCH a.b"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(A.class); Root a = cq.from(A.class); a.fetch(A_.b); @@ -195,7 +195,7 @@ public void testOuterFetchJoin() { String jpql = "select a from A a LEFT JOIN FETCH a.b"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(A.class); Root a = cq.from(A.class); a.fetch(A_.b, JoinType.LEFT); Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestMetaModelTypesafeCriteria.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestMetaModelTypesafeCriteria.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestMetaModelTypesafeCriteria.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestMetaModelTypesafeCriteria.java Wed Aug 26 18:54:30 2009 @@ -131,7 +131,7 @@ + "LEFT JOIN c.orders o " + "WHERE c.status = 1"; - CriteriaQuery q = cb.createQuery(); + CriteriaQuery q = cb.createQuery(Customer.class); Root c = q.from(Customer.class); SetJoin o = c.join(customer_.getSet("orders", Order.class), JoinType.LEFT); @@ -394,13 +394,12 @@ String jpql = "SELECT DISTINCT emp FROM Employee emp WHERE EXISTS (" + "SELECT spouseEmp FROM Employee spouseEmp WHERE spouseEmp = " + "emp.spouse)"; - CriteriaQuery q = cb.createQuery(); + CriteriaQuery q = cb.createQuery(Employee.class); Root emp = q.from(Employee.class); Subquery sq = q.subquery(Employee.class); Root spouseEmp = sq.from(Employee.class); sq.select(spouseEmp); - sq.where(cb.equal(spouseEmp, emp.get(employee_.getSingularAttribute("spouse", - Employee.class)))); + sq.where(cb.equal(spouseEmp, emp.get(employee_.getSingularAttribute("spouse", Employee.class)))); q.where(cb.exists(sq)); q.distinct(true); @@ -412,7 +411,7 @@ + "SELECT m.salary FROM Manager m WHERE m.department =" + " emp.department)"; - CriteriaQuery q = cb.createQuery(); + CriteriaQuery q = cb.createQuery(Employee.class); Root emp = q.from(Employee.class); Subquery sq = q.subquery(BigDecimal.class); @@ -430,7 +429,7 @@ public void testCorrelatedSubqueryWithCount() { String jpql = "SELECT c FROM Customer c WHERE " + "(SELECT COUNT(o) FROM c.orders o) > 10"; - CriteriaQuery q = cb.createQuery(); + CriteriaQuery q = cb.createQuery(Customer.class); Root c1 = q.from(Customer.class); Subquery sq3 = q.subquery(Long.class); Root c2 = sq3.correlate(c1); @@ -445,7 +444,7 @@ String jpql = "SELECT o FROM Order o WHERE 10000 < ALL (" + "SELECT a.balance FROM o.customer c JOIN c.accounts a)"; - CriteriaQuery q = cb.createQuery(); + CriteriaQuery q = cb.createQuery(Order.class); Root o = q.from(Order.class); Subquery sq = q.subquery(Integer.class); @@ -464,7 +463,7 @@ String jpql = "SELECT o FROM Order o JOIN o.customer c " + "WHERE 10000 < ALL (SELECT a.balance FROM c.accounts a)"; - CriteriaQuery q = cb.createQuery(); + CriteriaQuery q = cb.createQuery(Order.class); Root o = q.from(Order.class); Join c = o.join(Order_.customer); Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypeSafeCondExpression.java Wed Aug 26 18:54:30 2009 @@ -57,8 +57,8 @@ public void testNothingUsingCriteria() { String query = "SELECT o FROM CompUser o"; - CriteriaQuery cq = cb.createQuery(); - cq.from(CompUser.class); + CriteriaQuery cq = cb.createQuery(CompUser.class); + cq.select(cq.from(CompUser.class)); assertEquivalence(cq, query); } @@ -543,7 +543,7 @@ public void testTypeExpression5() { String query = "SELECT e FROM CompUser e where TYPE(e) in (MaleUser)"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(CompUser.class); Root e = cq.from(CompUser.class); cq.where(cb.in(e.type()).value(MaleUser.class)); @@ -554,7 +554,7 @@ String query = "SELECT e FROM CompUser e where TYPE(e) not in " + "(MaleUser, FemaleUser)"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(CompUser.class); Root e = cq.from(CompUser.class); cq.where(cb.in(e.type()).value(MaleUser.class).value(FemaleUser.class) .negate()); Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypesafeCriteria.java Wed Aug 26 18:54:30 2009 @@ -175,17 +175,15 @@ public void testInPredicate() { String jpql = "select a from Account a where a.name in ('X','Y','Z')"; - CriteriaQuery c = cb.createQuery(); + CriteriaQuery c = cb.createQuery(Account.class); Root account = c.from(Account.class); - c.where(cb.in(account.get(Account_.name)).value("X").value("Y").value( - "Z")); + c.where(cb.in(account.get(Account_.name)).value("X").value("Y").value("Z")); assertEquivalence(c, jpql); } public void testInPredicateWithPath() { - String jpql = - "select a from Account a where a.owner.name in ('X','Y','Z')"; - CriteriaQuery c = cb.createQuery(); + String jpql = "select a from Account a where a.owner.name in ('X','Y','Z')"; + CriteriaQuery c = cb.createQuery(Account.class); Root account = c.from(Account.class); c.where(cb.in(account.get(Account_.owner).get(Person_.name)).value("X") .value("Y").value("Z")); @@ -230,7 +228,7 @@ public void testSimplePath() { String jpql = "select a from Account a where a.owner.name='Pinaki'"; - CriteriaQuery c = cb.createQuery(); + CriteriaQuery c = cb.createQuery(Account.class); Root a = c.from(Account.class); c.where(cb.equal(a.get(Account_.owner).get(Person_.name), "Pinaki")); @@ -239,7 +237,7 @@ public void testSimpleLeftJoin() { String jpql = "SELECT c FROM Customer c LEFT JOIN c.orders o "; - CriteriaQuery c = cb.createQuery(); + CriteriaQuery c = cb.createQuery(Customer.class); c.from(Customer.class).join(Customer_.orders, JoinType.LEFT); assertEquivalence(c, jpql); } @@ -247,7 +245,7 @@ public void testMultipartNavigation() { String jpql = "select a from A a where a.b.age=22"; - CriteriaQuery cq = cb.createQuery(); + CriteriaQuery cq = cb.createQuery(A.class); Root a = cq.from(A.class); cq.where(cb.equal(a.get(A_.b).get(B_.age), 22)); Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java Wed Aug 26 18:54:30 2009 @@ -1531,14 +1531,17 @@ } /** - * Crete a query from the given CritriaQuery. + * Create a query from the given CritriaQuery. * Compile to register the parameters in this query. */ public TypedQuery createQuery(CriteriaQuery criteriaQuery) { + CriteriaQueryImpl impl = (CriteriaQueryImpl)criteriaQuery; + impl.assertRoot(); + impl.assertSelection(); org.apache.openjpa.kernel.Query kernelQuery =_broker.newQuery(CriteriaBuilder.LANG_CRITERIA, criteriaQuery); kernelQuery.compile(); QueryImpl facadeQuery = new QueryImpl(this, _ret, kernelQuery); - Set> params = ((CriteriaQueryImpl)criteriaQuery).getParameters(); + Set> params = impl.getParameters(); for (ParameterExpression param : params) { facadeQuery.declareParameter(param, param); Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CompoundSelections.java Wed Aug 26 18:54:30 2009 @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import javax.persistence.Tuple; import javax.persistence.TupleElement; @@ -77,7 +78,7 @@ * selection */ public final List> getCompoundSelectionItems() { - return Collections.unmodifiableList(_args); + return _args == null ? Collections.EMPTY_LIST : new CopyOnWriteArrayList>(_args); } void assertNoCompoundSelection(Selection...args) { Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaExpressionBuilder.java Wed Aug 26 18:54:30 2009 @@ -244,7 +244,7 @@ Map, Value> exp2Vals) { List> selections = q.getSelectionList(); MetamodelImpl model = q.getMetamodel(); - if (isDefaultProjection(selections, q)) { + if (q.isDefaultProjection()) { exps.projections = new Value[0]; return ; } @@ -300,18 +300,18 @@ } - protected boolean isDefaultProjection(List> selections, CriteriaQueryImpl q) { - if (selections == null) - return true; - if (selections.size() != 1) - return false; - Selection sel = selections.get(0); - if (q.getRoots() != null && sel == q.getRoot()) - return true; - if ((sel instanceof PathImpl) && ((PathImpl)sel)._correlatedPath != null) - return true; - return false; - } +// protected boolean isDefaultProjection(List> selections, CriteriaQueryImpl q) { +// if (selections == null) +// return true; +// if (selections.size() != 1) +// return false; +// Selection sel = selections.get(0); +// if (q.getRoots() != null && sel == q.getRoot()) +// return true; +// if ((sel instanceof PathImpl) && ((PathImpl)sel)._correlatedPath != null) +// return true; +// return false; +// } protected void evalFetchJoin(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl q) { List iPaths = new ArrayList(); Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaQueryImpl.java Wed Aug 26 18:54:30 2009 @@ -27,6 +27,8 @@ import java.util.Map; import java.util.Set; import java.util.Stack; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CopyOnWriteArraySet; import javax.persistence.criteria.AbstractQuery; import javax.persistence.criteria.CriteriaQuery; @@ -45,6 +47,7 @@ import org.apache.openjpa.kernel.exps.ExpressionFactory; import org.apache.openjpa.kernel.exps.QueryExpressions; import org.apache.openjpa.kernel.exps.Value; +import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.persistence.meta.MetamodelImpl; import org.apache.openjpa.persistence.meta.Types; @@ -62,6 +65,8 @@ * @since 2.0.0 */ public class CriteriaQueryImpl implements CriteriaQuery, AliasContext { + private static final Localizer _loc = Localizer.forPackage(CriteriaQueryImpl.class); + private final MetamodelImpl _model; private Set> _roots; private PredicateImpl _where; @@ -124,7 +129,7 @@ } public List getOrderList() { - return _orders; + return _orders == null ? Collections.EMPTY_LIST : new CopyOnWriteArrayList(_orders); } /** @@ -273,11 +278,8 @@ } public Root from(EntityType entity) { - Root root = new RootImpl((Types.Entity)entity); - if (_roots == null) { - _roots = new LinkedHashSet>(); - } - _roots.add(root); + RootImpl root = new RootImpl((Types.Entity)entity); + addRoot(root); return root; } @@ -285,12 +287,12 @@ public Root from(Class cls) { EntityType entity = _model.entity(cls); if (entity == null) - throw new IllegalArgumentException(cls + " is not an entity"); + throw new IllegalArgumentException(_loc.get("root-non-entity", cls).getMessage()); return from(entity); } public List> getGroupList() { - return _groups; + return _groups == null ? Collections.EMPTY_LIST : new CopyOnWriteArrayList>(_groups); } public PredicateImpl getGroupRestriction() { @@ -304,16 +306,19 @@ public Set> getRoots() { return _roots; } - - public void setRoots (Set> roots) { - this._roots = roots; - } public Root getRoot() { assertRoot(); return _roots.iterator().next(); } - + + void addRoot(RootImpl root) { + if (_roots == null) { + _roots = new LinkedHashSet>(); + } + _roots.add(root); + } + public boolean isDistinct() { return _distinct; } @@ -352,7 +357,12 @@ public void assertRoot() { if (_roots == null || _roots.isEmpty()) - throw new IllegalStateException("no root is set"); + throw new IllegalStateException(_loc.get("root-undefined").getMessage()); + } + + public void assertSelection() { + if (_selection == null && !isDefaultProjection()) + throw new IllegalStateException(_loc.get("select-undefined").getMessage()); } // @@ -535,4 +545,22 @@ boolean isMultiselect() { return _selection instanceof CompoundSelections.MultiSelection; } + + protected boolean isDefaultProjection() { + if (_selections == null) { + return _roots != null && _roots.size() == 1 && getRoot().getModel().getJavaType() == _resultClass; + } + if (_selections.size() != 1) { + return false; + } + Selection sel = _selections.get(0); + if (getRoots() != null && sel == getRoot()) { + return true; + } + if ((sel instanceof PathImpl) && ((PathImpl)sel)._correlatedPath != null) { + return true; + } + return false; + } + } Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PredicateImpl.java Wed Aug 26 18:54:30 2009 @@ -19,7 +19,9 @@ package org.apache.openjpa.persistence.criteria; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import javax.persistence.criteria.Expression; import javax.persistence.criteria.Predicate; @@ -61,7 +63,7 @@ } public List> getExpressions() { - return _exps; + return _exps == null ? Collections.EMPTY_LIST : new CopyOnWriteArrayList>(_exps); } public BooleanOperator getOperator() { Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java?rev=808158&r1=808157&r2=808158&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/SubqueryImpl.java Wed Aug 26 18:54:30 2009 @@ -181,12 +181,7 @@ Types.Entity entity = (Types.Entity)root.getModel(); RootImpl corrRoot = new RootImpl(entity); corrRoot.setCorrelatedPath((RootImpl)root); - Set> roots = getRoots(); - if (roots == null) { - roots = new LinkedHashSet>(); - _delegate.setRoots(roots); - } - roots.add(corrRoot); + _delegate.addRoot(corrRoot); return corrRoot; } @@ -271,8 +266,7 @@ * Convert this path to a kernel path value. */ @Override - public Value toValue(ExpressionFactory factory, MetamodelImpl model, - CriteriaQueryImpl q) { + public Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl q) { final boolean subclasses = true; CriteriaExpressionBuilder exprBuilder = new CriteriaExpressionBuilder(); String alias = q.getAlias(this); Added: openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/criteria/localizer.properties URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/criteria/localizer.properties?rev=808158&view=auto ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/criteria/localizer.properties (added) +++ openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/criteria/localizer.properties Wed Aug 26 18:54:30 2009 @@ -0,0 +1,24 @@ +# 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. + +root-non-entity: {0} can not be selected as the root of \ + criteria query because it is not an entity. +root-undefined: No root is defined for criteria query. \ + Use CriteriaQuery.from(Class) to define a root. +select-undefined: No terms is selected for criteria query. \ + Use CriteriaQuery.select() or multiselect() to select \ + projection terms for the query. \ No newline at end of file Propchange: openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/criteria/localizer.properties ------------------------------------------------------------------------------ svn:eol-style = native