openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fa...@apache.org
Subject svn commit: r676467 - in /openjpa: branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jd...
Date Mon, 14 Jul 2008 03:46:45 GMT
Author: fancy
Date: Sun Jul 13 20:46:44 2008
New Revision: 676467

URL: http://svn.apache.org/viewvc?rev=676467&view=rev
Log:
OPENJPA-51 Incorrect SQL with syntax error for JPQL subqueries

Added:
    openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
    openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
    openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
    openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
Modified:
    openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java

Modified: openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=676467&r1=676466&r2=676467&view=diff
==============================================================================
--- openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
(original)
+++ openjpa/branches/1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
Sun Jul 13 20:46:44 2008
@@ -470,6 +470,63 @@
             else
                 _joinSyntax = _parent._joinSyntax;
         }
+        
+        if (_parent.getAliases() == null || _subPath == null)
+            return;
+        
+        // resolve aliases for subselect from parent
+        Set entries = _parent.getAliases().entrySet();
+        Iterator it = entries.iterator();
+        while (it.hasNext()) {
+        	Map.Entry entry = (Map.Entry) it.next();
+            Object key = entry.getKey();
+            Integer alias = (Integer) entry.getValue();
+            if (key.toString().indexOf(_subPath) != -1) {
+                if (_aliases == null)
+                    _aliases = new HashMap();
+                _aliases.put(key, alias);
+
+                Object tableString = _parent.getTables().get(alias);
+                if (_tables == null)
+                    _tables = new TreeMap();
+                _tables.put(alias, tableString);
+                
+                _removedAliasFromParent.set(alias.intValue());
+            }
+        }
+        
+        if (_aliases != null) {
+            // aliases moved into subselect should be removed from parent
+            entries = _aliases.entrySet();
+            it = entries.iterator();
+            while (it.hasNext()) {
+            	Map.Entry entry = (Map.Entry) it.next();
+                Object key = entry.getKey();
+                Integer alias = (Integer) entry.getValue();
+                if (key.toString().indexOf(_subPath) != -1) {
+                    _parent.removeAlias(key);
+
+                    Object tableString = _parent.getTables().get(alias);
+                    _parent.removeTable(alias);
+                }
+            }
+        }
+    }
+    
+    public Map getAliases() {
+        return _aliases;
+    }
+    
+    public void removeAlias(Object key) {
+        _aliases.remove(key);
+    }
+    
+    public Map getTables() {
+        return _tables;
+    }
+    
+    public void removeTable(Object key) {
+        _tables.remove(key);
     }
 
     public Select getFromSelect() {
@@ -1492,8 +1549,13 @@
             return;
         if (_parent._joins != null && !_parent._joins.isEmpty()) {
             boolean removed = false;
-            if (!_removedAliasFromParent.isEmpty())
-                removed = _parent._joins.joins().removeAll(pj.joins());
+            if (!_removedAliasFromParent.isEmpty()) {
+                for (Iterator itr = pj.joins().iterator(); itr.hasNext();) {
+                   Join jn = (Join) itr.next();
+                   if (_aliases.containsValue(new Integer(jn.getIndex1())))
+                       removed = _parent._joins.joins().remove(jn);
+                }
+            }
             if (!removed)
                 pj.joins().removeAll(_parent._joins.joins());
         }

Added: openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java?rev=676467&view=auto
==============================================================================
--- openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
(added)
+++ openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
Sun Jul 13 20:46:44 2008
@@ -0,0 +1,120 @@
+/*
+ * 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.query;
+
+import javax.persistence.*;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.ArrayList;
+
+@Entity
+@Table(name="TCUSTOMER")
+public class Customer {
+
+    @Embeddable
+	public static class CustomerKey implements Serializable {
+		public String countryCode;
+		public int id;
+		
+		public CustomerKey(){}
+		
+		public  CustomerKey(String cc, int id){
+			countryCode=cc;
+			this.id=id;
+		}
+		
+		public String toString() {
+			return countryCode+"/"+id;
+		}
+		@Override
+		public boolean equals(Object obj){
+			if (obj==this) return true;
+			if ( ! (obj instanceof CustomerKey) ) return false;
+			CustomerKey key = (CustomerKey)obj;
+			if (key.countryCode.equals(this.countryCode) && 
+					key.id==this.id) return true;
+			return false;
+		}
+		
+		@Override
+		public int hashCode() {
+			return this.countryCode.hashCode()
+				^ this.id;
+		}
+	}
+	
+	public enum CreditRating { POOR, GOOD, EXCELLENT };
+	
+	@EmbeddedId
+	 CustomerKey cid;
+	@Column(length=30)
+    @Basic
+	 String name;
+	@Enumerated
+    @Basic
+	 CreditRating creditRating;
+	@Version
+	 long version;
+	
+    @OneToMany(fetch=FetchType.EAGER, mappedBy="customer")
+    private Collection<Order> orders = new ArrayList<Order>();
+	
+	public Customer() {}
+	
+	public Customer(CustomerKey cid, String name, CreditRating rating){
+		this.cid=cid;
+		this.name=name;
+		this.creditRating=rating;
+	}
+	
+
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public CreditRating getRating() {
+		return creditRating;
+	}
+	public void setRating(CreditRating rating) {
+		this.creditRating = rating;
+	}
+
+	public Collection<Order> getOrders() {
+		return orders;
+	}
+	public void setOrders(Collection<Order> orders) {
+		this.orders = orders;
+	}
+	
+	public String toString() {
+		return "Customer:"+cid+" name:"+name; 
+	}
+
+	public CustomerKey getCid() {
+		return cid;
+	}
+
+	public void setCid(CustomerKey cid) {
+		this.cid = cid;
+	}
+}
+

Added: openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java?rev=676467&view=auto
==============================================================================
--- openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
(added)
+++ openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
Sun Jul 13 20:46:44 2008
@@ -0,0 +1,87 @@
+/*
+ * 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.query;
+
+import javax.persistence.*;
+
+import java.util.Collection;
+import java.util.ArrayList;
+
+@Entity
+@Table(name="TORDER")
+public class Order {
+	@Id 
+	@GeneratedValue(strategy=GenerationType.IDENTITY)
+	 int oid;
+	
+	 double amount;
+	 boolean delivered;
+	 
+	@ManyToOne (fetch=FetchType.EAGER)
+	 Customer customer;
+	
+	@OneToMany (fetch=FetchType.EAGER , mappedBy="order")
+	 Collection<OrderItem> lineitems = new ArrayList<OrderItem>();
+	@Version
+	long version;
+	
+	public Order(){}
+	
+	public Order(  double amt, boolean delivered, Customer c){
+		amount=amt;
+		this.delivered=delivered;
+		customer=c;
+		if (c!=null) c.getOrders().add(this);
+	}
+	
+	public double getAmount() {
+		return amount;
+	}
+	public void setAmount(double amount) {
+		this.amount = amount;
+	}
+	public Customer getCustomer() {
+		return customer;
+	}
+	public void setCustomer(Customer customer) {
+		this.customer = customer;
+	}
+	public boolean isDelivered() {
+		return delivered;
+	}
+	public void setDelivered(boolean delivered) {
+		this.delivered = delivered;
+	}
+	public int getOid() {
+		return oid;
+	}
+	
+	public String toString(){
+		return "Order:"+oid+" amount:"+amount+" delivered:"+delivered+" customer:"+
+		 ( customer!=null ? customer.getCid()  :  -1 );
+	}
+
+	public Collection<OrderItem> getLineitems() {
+		return lineitems;
+	}
+
+	public void setLineitems(Collection<OrderItem> lineitems) {
+		this.lineitems = lineitems;
+	}
+}

Added: openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java?rev=676467&view=auto
==============================================================================
--- openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
(added)
+++ openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
Sun Jul 13 20:46:44 2008
@@ -0,0 +1,76 @@
+/*
+ * 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.query;
+import javax.persistence.*;
+@Entity
+@Table(name="TORDERITEM")
+public class OrderItem {
+	@Id 
+	@GeneratedValue(strategy=GenerationType.IDENTITY)
+	int lid;
+	
+	int quantity;
+	double cost;
+	 
+	@ManyToOne (fetch=FetchType.EAGER)
+	Order order;
+	
+	@Version
+	long version;
+	
+	public OrderItem(){}
+
+    public OrderItem( int quantity, double cost, Order o){
+        this.quantity=quantity;
+        this.cost=cost;
+        order = o;
+    }
+
+	public double getCost() {
+		return cost;
+	}
+
+	public void setCost(double cost) {
+		this.cost = cost;
+	}
+
+	public int getLid() {
+		return lid;
+	}
+
+	public void setLid(int lid) {
+		this.lid = lid;
+	}
+
+	public int getQuantity() {
+		return quantity;
+	}
+
+	public void setQuantity(int quantity) {
+		this.quantity = quantity;
+	}
+
+	public Order getOrder() {
+		return order;
+	}
+
+	public void setOrder(Order order) {
+		this.order = order;
+	}
+}

Added: openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
URL: http://svn.apache.org/viewvc/openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java?rev=676467&view=auto
==============================================================================
--- openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
(added)
+++ openjpa/branches/1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
Sun Jul 13 20:46:44 2008
@@ -0,0 +1,98 @@
+/*
+ * 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.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test JPQL subquery
+ */
+public class TestSubquery
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(Customer.class, Customer.CustomerKey.class,
+            Order.class, OrderItem.class, CLEAR_TABLES);
+    }
+
+    static String[]  querys = new String[] {
+        "select o.oid from Order o where o.customer.name =" +
+            " (select max(o2.customer.name) from Order o2" +
+            " where o.customer.cid.id = o2.customer.cid.id)",
+        "select o from Order o where o.customer.name =" +
+            " (select max(o2.customer.name) from Order o2" +
+            " where o.customer.cid.id = o2.customer.cid.id)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(i) from o.lineitems i)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(o.amount) from Order o)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(o.oid) from Order o)",
+        "select o.oid from Order o where o.amount >" +
+            " (select avg(o.amount) from Order o)",
+        "select c.name from Customer c where exists" +
+            " (select o from c.orders o where o.oid = 1) or exists" +
+            " (select o from c.orders o where o.oid = 2)",
+        "select c.name from Customer c, in(c.orders) o where o.amount between" +
+            " (select max(o.amount) from Order o) and" +
+            " (select avg(o.amount) from Order o) ",
+        "select o.oid from Order o where o.amount >" +
+            " (select sum(o2.amount) from Customer c, in(c.orders) o2) ",   
+        "select o.oid from Order o where o.amount between" +
+            " (select avg(o2.amount) from Customer c, in(c.orders) o2)" +
+            " and (select min(o2.amount) from Customer c, in(c.orders) o2)",
+        "select o.oid from Customer c, in(c.orders)o where o.amount >" +
+            " (select sum(o2.amount) from c.orders o2)",
+    // outstanding problem subqueries:
+    //"select o from Order o where o.amount > (select count(o) from Order o)",
+    //"select o from Order o where o.amount > (select count(o2) from Order o2)",
+    // "select c from Customer c left join c.orders p where not exists"
+    //   + " (select o2 from c.orders o2 where o2 = o",
+    };
+
+
+    static String[] updates = new String[] {
+        "update Order o set o.amount = 1000 where o.customer.name = " +
+            " (select max(o2.customer.name) from Order o2 " + 
+            " where o.customer.cid.id = o2.customer.cid.id)",  
+    };
+
+
+    public void testSubquery() {
+        EntityManager em = emf.createEntityManager();
+        for (int i = 0; i < querys.length; i++) {
+            String q = querys[i];
+            List rs = em.createQuery(q).getResultList();
+            assertEquals(0, rs.size());
+        }
+
+        em.getTransaction().begin();
+        for (int i = 0; i < updates.length; i++) {
+            int updateCount = em.createQuery(updates[i]).executeUpdate();
+            assertEquals(0, updateCount);
+        }
+
+        em.getTransaction().rollback();
+        em.close();
+    }
+}

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=676467&r1=676466&r2=676467&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Sun
Jul 13 20:46:44 2008
@@ -573,6 +573,59 @@
             else
                 _joinSyntax = _parent._joinSyntax;
         }
+        
+        if (_parent.getAliases() == null || _subPath == null)
+            return;
+        
+        // resolve aliases for subselect from parent
+        Set<Map.Entry> entries = _parent.getAliases().entrySet();
+        for (Map.Entry entry : entries) {
+            Object key = entry.getKey();
+            Integer alias = (Integer) entry.getValue();
+            if (key.toString().indexOf(_subPath) != -1) {
+                if (_aliases == null)
+                    _aliases = new HashMap();
+                _aliases.put(key, alias);
+
+                Object tableString = _parent.getTables().get(alias);
+                if (_tables == null)
+                    _tables = new TreeMap();
+                _tables.put(alias, tableString);
+                
+                _removedAliasFromParent.set(alias.intValue());
+            }
+        }
+        
+        if (_aliases != null) {
+            // aliases moved into subselect should be removed from parent
+            entries = _aliases.entrySet();
+            for (Map.Entry entry : entries) {
+                Object key = entry.getKey();
+                Integer alias = (Integer) entry.getValue();
+                if (key.toString().indexOf(_subPath) != -1) {
+                    _parent.removeAlias(key);
+
+                    Object tableString = _parent.getTables().get(alias);
+                    _parent.removeTable(alias);
+                }
+            }
+        }
+    }
+    
+    public Map getAliases() {
+        return _aliases;
+    }
+    
+    public void removeAlias(Object key) {
+        _aliases.remove(key);
+    }
+    
+    public Map getTables() {
+        return _tables;
+    }
+    
+    public void removeTable(Object key) {
+        _tables.remove(key);
     }
 
     public Select getFromSelect() {
@@ -1645,8 +1698,13 @@
             return;
         if (_parent._joins != null && !_parent._joins.isEmpty()) {
             boolean removed = false;
-            if (!_removedAliasFromParent.isEmpty())
-                removed = _parent._joins.joins().removeAll(pj.joins());
+            if (!_removedAliasFromParent.isEmpty()) {
+                for (Iterator itr = pj.joins().iterator(); itr.hasNext();) {
+                   Join jn = (Join) itr.next();
+                   if (_aliases.containsValue(jn.getIndex1()))
+                       removed = _parent._joins.joins().remove(jn);
+                }
+            }
             if (!removed)
                 pj.joins().removeAll(_parent._joins.joins());
         }

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java?rev=676467&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Customer.java
Sun Jul 13 20:46:44 2008
@@ -0,0 +1,120 @@
+/*
+ * 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.query;
+
+import javax.persistence.*;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.ArrayList;
+
+@Entity
+@Table(name="TCUSTOMER")
+public class Customer {
+
+    @Embeddable
+	public static class CustomerKey implements Serializable {
+		public String countryCode;
+		public int id;
+		
+		public CustomerKey(){}
+		
+		public  CustomerKey(String cc, int id){
+			countryCode=cc;
+			this.id=id;
+		}
+		
+		public String toString() {
+			return countryCode+"/"+id;
+		}
+		@Override
+		public boolean equals(Object obj){
+			if (obj==this) return true;
+			if ( ! (obj instanceof CustomerKey) ) return false;
+			CustomerKey key = (CustomerKey)obj;
+			if (key.countryCode.equals(this.countryCode) && 
+					key.id==this.id) return true;
+			return false;
+		}
+		
+		@Override
+		public int hashCode() {
+			return this.countryCode.hashCode()
+				^ this.id;
+		}
+	}
+	
+	public enum CreditRating { POOR, GOOD, EXCELLENT };
+	
+	@EmbeddedId
+	 CustomerKey cid;
+	@Column(length=30)
+    @Basic
+	 String name;
+	@Enumerated
+    @Basic
+	 CreditRating creditRating;
+	@Version
+	 long version;
+	
+    @OneToMany(fetch=FetchType.EAGER, mappedBy="customer")
+    private Collection<Order> orders = new ArrayList<Order>();
+	
+	public Customer() {}
+	
+	public Customer(CustomerKey cid, String name, CreditRating rating){
+		this.cid=cid;
+		this.name=name;
+		this.creditRating=rating;
+	}
+	
+
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public CreditRating getRating() {
+		return creditRating;
+	}
+	public void setRating(CreditRating rating) {
+		this.creditRating = rating;
+	}
+
+	public Collection<Order> getOrders() {
+		return orders;
+	}
+	public void setOrders(Collection<Order> orders) {
+		this.orders = orders;
+	}
+	
+	public String toString() {
+		return "Customer:"+cid+" name:"+name; 
+	}
+
+	public CustomerKey getCid() {
+		return cid;
+	}
+
+	public void setCid(CustomerKey cid) {
+		this.cid = cid;
+	}
+}
+

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java?rev=676467&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/Order.java
Sun Jul 13 20:46:44 2008
@@ -0,0 +1,87 @@
+/*
+ * 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.query;
+
+import javax.persistence.*;
+
+import java.util.Collection;
+import java.util.ArrayList;
+
+@Entity
+@Table(name="TORDER")
+public class Order {
+	@Id 
+	@GeneratedValue(strategy=GenerationType.IDENTITY)
+	 int oid;
+	
+	 double amount;
+	 boolean delivered;
+	 
+	@ManyToOne (fetch=FetchType.EAGER)
+	 Customer customer;
+	
+	@OneToMany (fetch=FetchType.EAGER , mappedBy="order")
+	 Collection<OrderItem> lineitems = new ArrayList<OrderItem>();
+	@Version
+	long version;
+	
+	public Order(){}
+	
+	public Order(  double amt, boolean delivered, Customer c){
+		amount=amt;
+		this.delivered=delivered;
+		customer=c;
+		if (c!=null) c.getOrders().add(this);
+	}
+	
+	public double getAmount() {
+		return amount;
+	}
+	public void setAmount(double amount) {
+		this.amount = amount;
+	}
+	public Customer getCustomer() {
+		return customer;
+	}
+	public void setCustomer(Customer customer) {
+		this.customer = customer;
+	}
+	public boolean isDelivered() {
+		return delivered;
+	}
+	public void setDelivered(boolean delivered) {
+		this.delivered = delivered;
+	}
+	public int getOid() {
+		return oid;
+	}
+	
+	public String toString(){
+		return "Order:"+oid+" amount:"+amount+" delivered:"+delivered+" customer:"+
+		 ( customer!=null ? customer.getCid()  :  -1 );
+	}
+
+	public Collection<OrderItem> getLineitems() {
+		return lineitems;
+	}
+
+	public void setLineitems(Collection<OrderItem> lineitems) {
+		this.lineitems = lineitems;
+	}
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java?rev=676467&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/OrderItem.java
Sun Jul 13 20:46:44 2008
@@ -0,0 +1,76 @@
+/*
+ * 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.query;
+import javax.persistence.*;
+@Entity
+@Table(name="TORDERITEM")
+public class OrderItem {
+	@Id 
+	@GeneratedValue(strategy=GenerationType.IDENTITY)
+	int lid;
+	
+	int quantity;
+	double cost;
+	 
+	@ManyToOne (fetch=FetchType.EAGER)
+	Order order;
+	
+	@Version
+	long version;
+	
+	public OrderItem(){}
+
+    public OrderItem( int quantity, double cost, Order o){
+        this.quantity=quantity;
+        this.cost=cost;
+        order = o;
+    }
+
+	public double getCost() {
+		return cost;
+	}
+
+	public void setCost(double cost) {
+		this.cost = cost;
+	}
+
+	public int getLid() {
+		return lid;
+	}
+
+	public void setLid(int lid) {
+		this.lid = lid;
+	}
+
+	public int getQuantity() {
+		return quantity;
+	}
+
+	public void setQuantity(int quantity) {
+		this.quantity = quantity;
+	}
+
+	public Order getOrder() {
+		return order;
+	}
+
+	public void setOrder(Order order) {
+		this.order = order;
+	}
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java?rev=676467&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
(added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubquery.java
Sun Jul 13 20:46:44 2008
@@ -0,0 +1,98 @@
+/*
+ * 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.query;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Test JPQL subquery
+ */
+public class TestSubquery
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(Customer.class, Customer.CustomerKey.class,
+            Order.class, OrderItem.class, CLEAR_TABLES);
+    }
+
+    static String[]  querys = new String[] {
+        "select o.oid from Order o where o.customer.name =" +
+            " (select max(o2.customer.name) from Order o2" +
+            " where o.customer.cid.id = o2.customer.cid.id)",
+        "select o from Order o where o.customer.name =" +
+            " (select max(o2.customer.name) from Order o2" +
+            " where o.customer.cid.id = o2.customer.cid.id)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(i) from o.lineitems i)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(o.amount) from Order o)",
+        "select o.oid from Order o where o.amount >" +
+            " (select count(o.oid) from Order o)",
+        "select o.oid from Order o where o.amount >" +
+            " (select avg(o.amount) from Order o)",
+        "select c.name from Customer c where exists" +
+            " (select o from c.orders o where o.oid = 1) or exists" +
+            " (select o from c.orders o where o.oid = 2)",
+        "select c.name from Customer c, in(c.orders) o where o.amount between" +
+            " (select max(o.amount) from Order o) and" +
+            " (select avg(o.amount) from Order o) ",
+        "select o.oid from Order o where o.amount >" +
+            " (select sum(o2.amount) from Customer c, in(c.orders) o2) ",   
+        "select o.oid from Order o where o.amount between" +
+            " (select avg(o2.amount) from Customer c, in(c.orders) o2)" +
+            " and (select min(o2.amount) from Customer c, in(c.orders) o2)",
+        "select o.oid from Customer c, in(c.orders)o where o.amount >" +
+            " (select sum(o2.amount) from c.orders o2)",
+    // outstanding problem subqueries:
+    //"select o from Order o where o.amount > (select count(o) from Order o)",
+    //"select o from Order o where o.amount > (select count(o2) from Order o2)",
+    // "select c from Customer c left join c.orders p where not exists"
+    //   + " (select o2 from c.orders o2 where o2 = o",
+    };
+
+
+    static String[] updates = new String[] {
+        "update Order o set o.amount = 1000 where o.customer.name = " +
+            " (select max(o2.customer.name) from Order o2 " + 
+            " where o.customer.cid.id = o2.customer.cid.id)",  
+    };
+
+
+    public void testSubquery() {
+        EntityManager em = emf.createEntityManager();
+        for (int i = 0; i < querys.length; i++) {
+            String q = querys[i];
+            List rs = em.createQuery(q).getResultList();
+            assertEquals(0, rs.size());
+        }
+
+        em.getTransaction().begin();
+        for (int i = 0; i < updates.length; i++) {
+            int updateCount = em.createQuery(updates[i]).executeUpdate();
+            assertEquals(0, updateCount);
+        }
+
+        em.getTransaction().rollback();
+        em.close();
+    }
+}



Mime
View raw message