You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2013/05/13 22:14:59 UTC

svn commit: r1482077 - in /openjpa/sandboxes/21: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ openjpa-jdbc/src/test/java/org/...

Author: ppoddar
Date: Mon May 13 20:14:59 2013
New Revision: 1482077

URL: http://svn.apache.org/r1482077
Log:
second draft of stored procedures. few tests or parameterization break.

Added:
    openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/Citizen.java   (with props)
    openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/City.java   (with props)
Removed:
    openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MultiQueryResultSetMapping.java
    openjpa/sandboxes/21/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/sql/TestStoredProcedure.java
Modified:
    openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java
    openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java
    openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
    openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/QueryResultMapping.java
    openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java
    openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java
    openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java
    openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java
    openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java
    openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestStoredProcedure.java
    openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AbstractQuery.java
    openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
    openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
    openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
    openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java
    openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java

Modified: openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java (original)
+++ openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java Mon May 13 20:14:59 2013
@@ -21,24 +21,23 @@ package org.apache.openjpa.jdbc.kernel;
 import java.sql.CallableStatement;
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
-import org.apache.openjpa.jdbc.kernel.SQLStoreQuery.SQLExecutor;
 import org.apache.openjpa.jdbc.meta.MappingRepository;
-import org.apache.openjpa.jdbc.meta.MultiQueryResultSetMapping;
 import org.apache.openjpa.jdbc.meta.QueryResultMapping;
 import org.apache.openjpa.jdbc.sql.DBDictionary;
 import org.apache.openjpa.jdbc.sql.StoredProcedure;
 import org.apache.openjpa.kernel.AbstractStoreQuery;
-import org.apache.openjpa.kernel.Query;
 import org.apache.openjpa.kernel.QueryContext;
 import org.apache.openjpa.kernel.QueryOperations;
-import org.apache.openjpa.kernel.AbstractStoreQuery.AbstractExecutor;
 import org.apache.openjpa.kernel.StoreQuery;
-import org.apache.openjpa.kernel.StoreQuery.Executor;
-import org.apache.openjpa.lib.jdbc.DelegatingCallableStatement;
 import org.apache.openjpa.lib.rop.ResultObjectProvider;
 import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MultiQueryMetaData;
+import org.apache.openjpa.meta.QueryMetaData;
+import org.apache.openjpa.util.InternalException;
 
 /**
  * Executes a stored procedure.
@@ -50,6 +49,7 @@ import org.apache.openjpa.meta.ClassMeta
 public class StoredProcedureQuery extends AbstractStoreQuery {
 	JDBCStore _store;
 	StoredProcedure _proc;
+	private MultiQueryMetaData _meta;
 	
 	public StoredProcedureQuery(JDBCStore store) {
 		_store = store;
@@ -59,21 +59,32 @@ public class StoredProcedureQuery extend
 		return QueryOperations.OP_SELECT;
 	}
 	
+	@Override
+	public boolean setQuery(Object meta) {
+		if (meta == null || meta instanceof MultiQueryMetaData) {
+			_meta = (MultiQueryMetaData)meta;
+			return true;
+		} else {
+			throw new InternalException("Unknown " + meta);
+		}
+	}
+	
     public Executor newDataStoreExecutor(ClassMetaData meta,  boolean subclasses) {
-    	MultiQueryResultSetMapping resultMapping = null;
-    	String mappingName = ctx.getResultMappingName();
-        if (mappingName != null) {
-            ClassLoader envLoader = ctx.getStoreContext().getClassLoader();
-            MappingRepository repos = _store.getConfiguration().getMappingRepositoryInstance();
-            QueryResultMapping mapping = repos.getQueryResultMapping(ctx.getResultMappingScope(), mappingName, 
-            		envLoader, true);
-            if (mapping instanceof MultiQueryResultSetMapping) {
-            	resultMapping = (MultiQueryResultSetMapping)mapping;
-            } else {
-            	throw new RuntimeException("Bad mapping [" + mappingName + "]");
-            } 
-        }
-        return new StoredProcedureQueryExecutor(this, resultMapping);
+    	List<QueryResultMapping> mappings = null;
+    	if (_meta != null) {
+    		List<QueryMetaData> parts = _meta.getComponents();
+    		if (parts != null && !parts.isEmpty()) {
+    			mappings = new ArrayList<QueryResultMapping>();
+                MappingRepository repos = _store.getConfiguration().getMappingRepositoryInstance();
+    			for (int i = 0; i < parts.size(); i++) {
+    				QueryResultMapping mapping = repos.getQueryResultMapping(ctx.getResultMappingScope(), 
+    						parts.get(i).getResultSetMappingName(), 
+    	            		null, true);    
+    				mappings.add(mapping);
+    			}
+    		}
+    	}
+        return new StoredProcedureQueryExecutor(this, mappings);
     }
 
     public boolean supportsParameterDeclarations() {
@@ -94,11 +105,11 @@ public class StoredProcedureQuery extend
     
     
     public class StoredProcedureQueryExecutor  extends AbstractExecutor {
-    	private MultiQueryResultSetMapping _resultMapping;
+    	private List<QueryResultMapping> _resultMappings;
     	
-    	public StoredProcedureQueryExecutor(StoredProcedureQuery q, MultiQueryResultSetMapping resultMapping) {
+    	public StoredProcedureQueryExecutor(StoredProcedureQuery q, List<QueryResultMapping> resultMapping) {
             QueryContext ctx = q.getContext();
-            _resultMapping = resultMapping;
+            _resultMappings = resultMapping;
        		// Look for the named Stored Procedure in the database
             String procName = ctx.getQueryString();
     		_proc = getStoredProcedure(_store.getConnection(), _store.getDBDictionary(), procName);
@@ -135,7 +146,7 @@ public class StoredProcedureQuery extend
 					dict.setUnknown(stmnt, i+1, params[i], null);
 				}
                 JDBCFetchConfiguration fetch = (JDBCFetchConfiguration)q.getContext().getFetchConfiguration();
-            	ResultObjectProvider rop = new XROP(_resultMapping, _store, fetch, stmnt);
+            	ResultObjectProvider rop = new XROP(_resultMappings, _store, fetch, stmnt);
             	rop.open();
             	return rop;
 			} catch (Exception e) {

Modified: openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java (original)
+++ openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java Mon May 13 20:14:59 2013
@@ -22,8 +22,9 @@ package org.apache.openjpa.jdbc.kernel;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.List;
 
-import org.apache.openjpa.jdbc.meta.MultiQueryResultSetMapping;
+import org.apache.openjpa.jdbc.meta.QueryResultMapping;
 import org.apache.openjpa.jdbc.sql.ResultSetResult;
 import org.apache.openjpa.lib.rop.BatchedResultObjectProvider;
 import org.apache.openjpa.lib.rop.ResultObjectProvider;
@@ -38,15 +39,15 @@ import org.apache.openjpa.util.InternalE
 public class XROP implements BatchedResultObjectProvider {
 	private final PreparedStatement stmt;
 	private final JDBCFetchConfiguration fetch;
-	private final MultiQueryResultSetMapping _multi;
-	int index;
+	private final List<QueryResultMapping> _multi;
+	private int index;
 	private final JDBCStore store;
 	// Result of first execution 
 	private boolean executionResult;
 	
-	public XROP(MultiQueryResultSetMapping mapping, JDBCStore store, JDBCFetchConfiguration fetch, 
+	public XROP(List<QueryResultMapping> mappings, JDBCStore store, JDBCFetchConfiguration fetch, 
 			PreparedStatement stmt) {
-		_multi = mapping;
+		_multi = mappings;
 		this.stmt = stmt;
 		this.fetch = fetch;
 		this.store = store;
@@ -73,7 +74,9 @@ public class XROP implements BatchedResu
 	 * Gets the current result set, wraps it with a {@link ResultSetResult}, then wraps
 	 * again with appropriate ROP based on the result set mapping. 
 	 * <br>
-	 * The ResultSet and the associated connection must not be closed
+	 * The ResultSet and the associated connection must not be closed.
+	 * 
+	 * @return a provider or null if the underlying statement has no more results.
 	 */
 	@Override
 	public ResultObjectProvider getResultObject() throws Exception {
@@ -87,10 +90,8 @@ public class XROP implements BatchedResu
 		if (_multi == null) {
 			return new SQLProjectionResultObjectProvider(store, fetch, res, null);
 		}
-		return _multi.isClassMapping()
-		    ? new GenericResultObjectProvider(_multi.getResultType(index++), store, fetch, res)
-		    : new MappedQueryResultObjectProvider(_multi.getMapping(index++), store, fetch, res);
-		    
+		QueryResultMapping mapping = _multi.get(index++);
+		return new MappedQueryResultObjectProvider(mapping, store, fetch, res);
 	}
 
 

Modified: openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java (original)
+++ openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java Mon May 13 20:14:59 2013
@@ -93,7 +93,9 @@ import org.apache.openjpa.meta.ClassMeta
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.JavaTypes;
 import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.meta.MultiQueryMetaData;
 import org.apache.openjpa.meta.Order;
+import org.apache.openjpa.meta.QueryMetaData;
 import org.apache.openjpa.meta.SequenceMetaData;
 import org.apache.openjpa.meta.ValueMetaData;
 import org.apache.openjpa.util.MetaDataException;
@@ -104,10 +106,10 @@ import org.apache.openjpa.util.UserExcep
  *
  * @author Abe White
  */
+@SuppressWarnings("serial")
 public class MappingRepository extends MetaDataRepository {
 
-    private static final Localizer _loc = Localizer.forPackage
-        (MappingRepository.class);
+    private static final Localizer _loc = Localizer.forPackage(MappingRepository.class);
 
     private transient DBDictionary _dict = null;
     private transient MappingDefaults _defaults = null;
@@ -222,6 +224,7 @@ public class MappingRepository extends M
             throw new MetaDataException(_loc.get("no-query-res", cls, name));
         return res;
     }
+    
 
     /**
      * Returned the query result mapping with the given name.
@@ -232,13 +235,13 @@ public class MappingRepository extends M
 
         // check cache
         Object key = getQueryResultKey(cls, name);
-        QueryResultMapping res = (QueryResultMapping) _results.get(key);
+        QueryResultMapping res = _results.get(key);
         if (res != null)
             return res;
 
         // get metadata for class, which will find results in metadata file
         if (cls != null && getMetaData(cls, envLoader, false) != null) {
-            res = (QueryResultMapping) _results.get(key);
+            res = _results.get(key);
             if (res != null)
                 return res;
         }
@@ -246,8 +249,7 @@ public class MappingRepository extends M
             return null;
 
         if (cls == null)
-            cls = getMetaDataFactory()
-                    .getResultSetMappingScope(name, envLoader);
+            cls = getMetaDataFactory().getResultSetMappingScope(name, envLoader);
         // not in cache; load
         getMetaDataFactory().load(cls, MODE_META | MODE_MAPPING, envLoader);
         return (QueryResultMapping) _results.get(key);
@@ -259,12 +261,12 @@ public class MappingRepository extends M
     public QueryResultMapping[] getQueryResultMappings() {
         if (_locking) {
             synchronized (this) {
-                Collection values = _results.values();
-                return (QueryResultMapping[]) values.toArray(new QueryResultMapping[values.size()]);
+                Collection<QueryResultMapping> values = _results.values();
+                return values.toArray(new QueryResultMapping[values.size()]);
             }
         } else {
-            Collection values = _results.values();
-            return (QueryResultMapping[]) values.toArray(new QueryResultMapping[values.size()]);
+            Collection<QueryResultMapping> values = _results.values();
+            return values.toArray(new QueryResultMapping[values.size()]);
         }
     }
 
@@ -272,34 +274,31 @@ public class MappingRepository extends M
      * Return the cached query result mapping with the given name, or null if
      * none.
      */
-    public QueryResultMapping getCachedQueryResultMapping(Class cls, String name) {
+    public QueryResultMapping getCachedQueryResultMapping(Class<?> cls, String name) {
         if (_locking) {
             synchronized (this) {
-                return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+                return _results.get(getQueryResultKey(cls, name));
             }
         } else {
-            return (QueryResultMapping) _results.get(getQueryResultKey(cls, name));
+            return _results.get(getQueryResultKey(cls, name));
         }
     }
 
     /**
      * Add a query result mapping.
      */
-    public QueryResultMapping addQueryResultMapping(Class cls, String name) {
+    public QueryResultMapping addQueryResultMapping(QueryResultMapping mapping) {
         if (_locking) {
             synchronized (this) {
-                return addQueryResultMappingInternal(cls, name);
+                return addQueryResultMappingInternal(mapping);
             }
         } else {
-            return addQueryResultMappingInternal(cls, name);
+            return addQueryResultMappingInternal(mapping);
         }
     }
 
-    private QueryResultMapping addQueryResultMappingInternal(Class cls, String name) {
-        QueryResultMapping res = new QueryResultMapping(name, this);
-        res.setDefiningType(cls);
-        _results.put(getQueryResultKey(res), res);
-        return res;
+    private QueryResultMapping addQueryResultMappingInternal(QueryResultMapping mapping) {
+        return _results.put(getQueryResultKey(mapping), mapping);
     }
 
     /**
@@ -318,7 +317,7 @@ public class MappingRepository extends M
     /**
      * Remove a query result mapping.
      */
-    public boolean removeQueryResultMapping(Class cls, String name) {
+    public boolean removeQueryResultMapping(Class<?> cls, String name) {
         if (_locking) {
             synchronized (this) {
                 if (name == null)
@@ -442,7 +441,7 @@ public class MappingRepository extends M
     }
 
     protected SequenceMetaData newSequenceMetaData(String name) {
-        return new SequenceMapping(name, this);
+        return new SequenceMapping(DBIdentifier.newSequence(name), this);
     }
 
     protected Order newValueOrder(FieldMetaData owner, boolean asc) {

Modified: openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/QueryResultMapping.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/QueryResultMapping.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/QueryResultMapping.java (original)
+++ openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/QueryResultMapping.java Mon May 13 20:14:59 2013
@@ -49,8 +49,7 @@ import serp.util.Strings;
 public class QueryResultMapping
     implements MetaDataModes, SourceTracker, Commentable {
 
-    private static final Localizer _loc = Localizer.forPackage
-        (QueryResultMapping.class);
+    private static final Localizer _loc = Localizer.forPackage(QueryResultMapping.class);
 
     private final String _name;
     protected final MappingRepository _repos;
@@ -72,7 +71,7 @@ public class QueryResultMapping
     /**
      * Construct with the given name.
      */
-    QueryResultMapping(String name, MappingRepository repos) {
+    public QueryResultMapping(String name, MappingRepository repos) {
         _name = name;
         _repos = repos;
     }

Modified: openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java (original)
+++ openjpa/sandboxes/21/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/ResultSetResult.java Mon May 13 20:14:59 2013
@@ -28,13 +28,16 @@ import java.sql.Clob;
 import java.sql.Connection;
 import java.sql.Ref;
 import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
@@ -57,38 +60,38 @@ public class ResultSetResult
 
     private final Connection _conn;
     private final Statement _stmnt;
-    private final ResultSet _rs;
+    private ResultSet _rs;
     private final DBDictionary _dict;
     private boolean _closeConn = true;
     private boolean _closeStatement = true;
     private int _row = -1;
     private int _size = -1;
-
+    private List<String> _columnLabels = new ArrayList<String>();
+    
     // optional; used to deserialize blobs containing refs to persistent objs
     private JDBCStore _store = null;
 
     /**
      * Constructor.
      */
-    public ResultSetResult(Connection conn, Statement stmnt,
-        ResultSet rs, DBDictionary dict) {
+    public ResultSetResult(Connection conn, Statement stmnt, ResultSet rs, DBDictionary dict) {
         if (stmnt == null)
             try {
                 stmnt = rs.getStatement();
             } catch (Throwable t) {
-            }
+        }
 
         _conn = conn;
         _stmnt = stmnt;
-        _rs = rs;
+        setResultSet(rs);
         _dict = dict;
+        
     }
 
     /**
      * Constructor.
      */
-    public ResultSetResult(Connection conn, Statement stmnt,
-        ResultSet rs, JDBCStore store) {
+    public ResultSetResult(Connection conn, Statement stmnt, ResultSet rs, JDBCStore store) {
         this(conn, stmnt, rs, store.getDBDictionary());
         setStore(store);
     }
@@ -96,11 +99,10 @@ public class ResultSetResult
     /**
      * Constructor.
      */
-    public ResultSetResult(Connection conn,
-        ResultSet rs, DBDictionary dict) {
+    public ResultSetResult(Connection conn, ResultSet rs, DBDictionary dict) {
         _conn = conn;
         _stmnt = null;
-        _rs = rs;
+        setResultSet(rs);
         _dict = dict;
     }
 
@@ -112,7 +114,7 @@ public class ResultSetResult
         throws SQLException {
         _stmnt = rs.getStatement();
         _conn = _stmnt.getConnection();
-        _rs = rs;
+        setResultSet(rs);
         _dict = dict;
     }
 
@@ -132,6 +134,23 @@ public class ResultSetResult
     public Statement getStatement() {
         return _stmnt;
     }
+    
+    private void setResultSet(ResultSet rs) {
+    	if (rs == null)
+    		throw new RuntimeException("Null JDBC ResultSet");
+    
+        try {
+        	_rs = rs;
+			ResultSetMetaData meta = _rs.getMetaData();
+			int nColumn = meta.getColumnCount();
+			for (int i = 1; i <= nColumn; i++) {
+				_columnLabels.add(meta.getColumnLabel(i).toUpperCase());
+			}
+		} catch (SQLException e) {
+			throw new RuntimeException(e);
+		}
+    }
+    
 
     /**
      * Return the backing result set.
@@ -383,8 +402,7 @@ public class ResultSetResult
         switch (metaTypeCode) {
             case JavaTypes.BOOLEAN:
             case JavaTypes.BOOLEAN_OBJ:
-                val = (getBooleanInternal(obj, joins)) ? Boolean.TRUE
-                    : Boolean.FALSE;
+                val = (getBooleanInternal(obj, joins)) ? Boolean.TRUE : Boolean.FALSE;
                 break;
             case JavaTypes.BYTE:
             case JavaTypes.BYTE_OBJ:
@@ -521,14 +539,16 @@ public class ResultSetResult
      */
     protected int findObject(Object obj, Joins joins)
         throws SQLException {
-        try {
-          String s1 = obj.toString();
-          DBIdentifier sName = DBIdentifier.newColumn(obj.toString());
-          return getResultSet().findColumn(_dict.convertSchemaCase(sName));
-        } catch (SQLException se) {
-            _dict.log.trace(se.getMessage());
-            return 0;
-        }
+    	    // JDBC index is 1-based
+         	int idx = _columnLabels.indexOf(obj.toString().toUpperCase()) + 1;
+        	if (idx < 1) {
+        		DBIdentifier sName = DBIdentifier.newColumn(obj.toString());
+        		idx = getResultSet().findColumn(_dict.convertSchemaCase(sName));               
+        	}
+        	if (idx < 1) {
+        		throw new SQLException(obj + " not in the avaialble columns " + _columnLabels);
+        	}
+        	return idx; 
     }
   
     protected InputStream getLOBStreamInternal(JDBCStore store, Object obj,

Modified: openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java (original)
+++ openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java Mon May 13 20:14:59 2013
@@ -21,6 +21,9 @@ package org.apache.openjpa.meta;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.openjpa.kernel.QueryLanguages;
+
+
 
 /**
  * Extends {@link QueryMetaData} to allow multiple {@link QueryMetaData#getResultType() result class} or 
@@ -35,16 +38,50 @@ import java.util.List;
  */
 @SuppressWarnings("serial")
 public class MultiQueryMetaData extends QueryMetaData {
-	private final List<Parameter> _params = new ArrayList<MultiQueryMetaData.Parameter>();
+	private final String _procedureName;
+	private final boolean _isTemporary;
 	private final List<QueryMetaData> _parts = new ArrayList<QueryMetaData>();
+	private final List<Parameter> _params = new ArrayList<MultiQueryMetaData.Parameter>();
 	
 	/**
-	 * Create this meta data given a scope of defiition and a name.
+	 * Create this meta data given a scope of definition, a logical identifier, a procedure name
+	 * and whether its usage is temporary.
 	 * @param scope defining scope
-	 * @param name name as an identifier
+	 * @param logicalName name as an identifier
+	 * @param procedureName name of the database procedure
 	 */
-	public MultiQueryMetaData(Class<?> scope, String name) {
-		super(scope, name);
+	public MultiQueryMetaData(Class<?> scope, String logicalName, String procedureName, boolean isTemporary) {
+		super(scope, logicalName, QueryLanguages.LANG_STORED_PROC);
+		_procedureName = procedureName;
+		_isTemporary = isTemporary;
+		_resultSetMappingName = logicalName + ".CompositeMapping";
+	}
+	
+	public String getProcedureName() {
+		return _procedureName;
+	}
+	
+	public List<QueryMetaData> getComponents() {
+		return _parts;
+	}
+	
+	/**
+	 * Affirms if this metadata is ephimeral. 
+	 * Ephimenral metadata is removed from the repository after usage.
+	 * @return
+	 */
+	public boolean isEphimeral() {
+		return _isTemporary;
+	}
+	
+	@Override
+	public void setResultSetMappingName(String name) {
+		throw new UnsupportedOperationException("Not allowed to set mapping name. It is automatically set");
+	}
+	
+	@Override
+	public void setResultType(Class<?> cls) {
+		throw new UnsupportedOperationException("Not allowed to set result type. It is automatically set");
 	}
 	
 	/**
@@ -58,12 +95,21 @@ public class MultiQueryMetaData extends 
 	 * 
 	 * @return the new part metadata
 	 */
-	public QueryMetaData addComponent() {
-		QueryMetaData part = new QueryMetaData(getDefiningType(), getName() + "#" + _parts.size());
+	public void addComponent(Class<?> resultClass) {
+		QueryMetaData part = new QueryMetaData(getDefiningType(), getName() + "#" + _parts.size(),
+				getLanguage());
+		part.setResultType(resultClass);
 		_parts.add(part);
-		return part;
 	}
 	
+	public void addComponent(String mappingName) {
+		QueryMetaData part = new QueryMetaData(getDefiningType(), getName() + "#" + _parts.size(),
+				getLanguage());
+		part.setResultSetMappingName(mappingName);
+		_parts.add(part);
+	}
+
+	
 	/**
 	 * Gets the component metadata at the given part index.
 	 * @param i a valid integer index
@@ -71,7 +117,8 @@ public class MultiQueryMetaData extends 
 	 */
 	public QueryMetaData getComponent(int i) {
 		if (i < 0 || i >= _parts.size()) {
-			throw new ArrayIndexOutOfBoundsException("Invalid index " + i + ". Available " + _parts.size() + " parts");
+			throw new ArrayIndexOutOfBoundsException("Invalid index " + i 
+					+ ". Available " + _parts.size() + " parts");
 		}
 		return _parts.get(i);
 	}

Modified: openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java (original)
+++ openjpa/sandboxes/21/openjpa-kernel/src/main/java/org/apache/openjpa/meta/QueryMetaData.java Mon May 13 20:14:59 2013
@@ -61,11 +61,10 @@ public class QueryMetaData
     private String[] _comments;
     private List<String> _hintKeys;
     private List<Object> _hintVals;
-    private String _resultSetMappingName;
+    protected String _resultSetMappingName;
     private int _lineNum;  
     private int _colNum;
     private String _srcName; 
-    private boolean _convertPositionalParametersToNamed;
     private OrderedMap<Object,Class<?>> _paramTypes;
     private long _start = 0;
     private long _end   = Long.MAX_VALUE;
@@ -74,26 +73,17 @@ public class QueryMetaData
     /**
      * Construct with the given name within the given scope.
      */
-    public QueryMetaData(Class<?> scope, String name) {
+    public QueryMetaData(Class<?> scope, String name, String lang) {
     	_class = scope;
         _name = name;
+        _language = lang;
     }
     
     public QueryMetaData(String name, Query q) {
     	_name  = name;
     	_class = null;
      	setFrom(q);
-    }
-    
-    
-    public boolean getConvertPositionalParametersToNamed() {
-    	return _convertPositionalParametersToNamed;
-    }
-    
-    public QueryMetaData setConvertPositionalParametersToNamed(boolean convert) {
-    	_convertPositionalParametersToNamed = convert;
-    	return this;
-    }
+    }    
 
     /**
      * Return the name for this query.
@@ -168,9 +158,9 @@ public class QueryMetaData
     /**
      * Set the language for this query.
      */
-    public void setLanguage(String language) {
-        _language = language;
-    }
+//    public void setLanguage(String language) {
+//        _language = language;
+//    }
 
     /**
      * The full query string, or null if none.
@@ -183,9 +173,9 @@ public class QueryMetaData
      * The full query string, or null if none.
      */
     public void setQueryString(String query) {
-        if (query != null && _convertPositionalParametersToNamed && JPQLParser.LANG_JPQL.equals(_language)) {
-            query = query.replaceAll("[\\?]", "\\:_");
-        }
+//        if (query != null && _convertPositionalParametersToNamed && JPQLParser.LANG_JPQL.equals(_language)) {
+//            query = query.replaceAll("[\\?]", "\\:_");
+//        }
         _query = query;
     }
 

Modified: openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java Mon May 13 20:14:59 2013
@@ -76,7 +76,6 @@ import org.apache.openjpa.jdbc.meta.Fiel
 import org.apache.openjpa.jdbc.meta.FieldMappingInfo;
 import org.apache.openjpa.jdbc.meta.MappingInfo;
 import org.apache.openjpa.jdbc.meta.MappingRepository;
-import org.apache.openjpa.jdbc.meta.MultiQueryResultSetMapping;
 import org.apache.openjpa.jdbc.meta.QueryResultMapping;
 import org.apache.openjpa.jdbc.meta.SequenceMapping;
 import org.apache.openjpa.jdbc.meta.ValueMapping;
@@ -361,8 +360,7 @@ public class AnnotationPersistenceMappin
                     parseSQLResultSetMappings(cm, (SqlResultSetMapping) anno);
                     break;
                 case SQL_RESULT_SET_MAPPINGS:
-                    parseSQLResultSetMappings(cm, ((SqlResultSetMappings) anno).
-                        value());
+                    parseSQLResultSetMappings(cm, ((SqlResultSetMappings) anno).value());
                     break;
                 case TABLE:
                     parseTable(cm, (Table) anno);
@@ -630,7 +628,8 @@ public class AnnotationPersistenceMappin
                 continue;
             }
 
-            result = repos.addQueryResultMapping(null, anno.name());
+            result = new QueryResultMapping(anno.name(), repos);
+            repos.addQueryResultMapping(result);
             result.setSource(getSourceFile(), cm.getDescribedType(), SourceTracker.SRC_ANNOTATIONS);
 
             for (EntityResult entity : anno.entities()) {
@@ -2171,29 +2170,25 @@ public class AnnotationPersistenceMappin
 	            throw new MetaDataException(_loc.get("stored-proc-no-dbname", el));
 			
 			// Query metadata name 
-			MultiQueryMetaData meta = new MultiQueryMetaData(_cls, proc.name());
+            MultiQueryMetaData meta = new MultiQueryMetaData(_cls, proc.name(), proc.procedureName(), false);
 			addQueryMetaData(el, meta);
-			meta.setResultSetMappingName(meta.getName()+ ".ResultSetMapping");
-	        meta.setLanguage(QueryLanguages.LANG_SQL);
+			
 	        // Important: The query string is the name of the database stored procedure 
 	        meta.setQueryString(proc.procedureName());
 	
 	        // For each mapping name/result class, add a component metadata
-	        // The spec restricts that either ResultMappingName or ResultClasses be specified, 
-	        // but not both.
+	        // The spec restricts that either ResultMappingName or ResultClasses be specified, but not both.
 	        // This is relevant because the order of mapping must match the order in which the
-	        // results are returned 
-	        MultiQueryResultSetMapping compositeMapping = new MultiQueryResultSetMapping(
-	        		meta.getName()+ ".ResultSetMapping", (MappingRepository)_repos);
+	        // components are returned 
 	        Class<?>[] resultClasses = proc.resultClasses();
 	        String[] resultSetMappings = proc.resultSetMappings();
 	        if (resultClasses.length > 0 && resultSetMappings.length > 0) 
 	        	throw new MetaDataException(_loc.get("stored-proc-both-mapping", el));
 	        for (Class<?> res : resultClasses) {
-	            meta.addComponent().setResultType(res);
+	            meta.addComponent(res);
 	        }
 	        for (String mapping : resultSetMappings) {
-	        	meta.addComponent().setResultSetMappingName(mapping);
+	        	meta.addComponent(mapping);
 	        }
 	        StoredProcedureParameter[] params = proc.parameters();
 	        for (StoredProcedureParameter param : params) {

Modified: openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/XMLPersistenceMappingParser.java Mon May 13 20:14:59 2013
@@ -1153,13 +1153,10 @@ public class XMLPersistenceMappingParser
             log.trace(_loc.get("parse-sqlrsmapping", name));
 
         MappingRepository repos = (MappingRepository) getRepository();
-        QueryResultMapping result = repos.getCachedQueryResultMapping
-            (null, name);
-        if (result != null && log.isWarnEnabled())
-            log.warn(_loc.get("override-sqlrsmapping", name,
-                currentLocation()));
-
-        result = repos.addQueryResultMapping(null, name);
+        QueryResultMapping result = new QueryResultMapping(name, repos);
+        if (repos.addQueryResultMapping(result) != null) {
+            log.warn(_loc.get("override-sqlrsmapping", name, currentLocation()));
+        }
         result.setListingIndex(_resultIdx++);
         addComments(result);
 

Added: openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/Citizen.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/Citizen.java?rev=1482077&view=auto
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/Citizen.java (added)
+++ openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/Citizen.java Mon May 13 20:14:59 2013
@@ -0,0 +1,103 @@
+/*
+ * 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.jdbc.mapping;
+
+import javax.persistence.ColumnResult;
+import javax.persistence.ConstructorResult;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedStoredProcedureQueries;
+import javax.persistence.NamedStoredProcedureQuery;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.SqlResultSetMappings;
+
+/**
+ * Used in testing Stored Procedure Query.
+ * 
+ * @see TestStoredProcedure
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+
+@NamedStoredProcedureQueries({
+	@NamedStoredProcedureQuery(
+			name=Citizen.LOGICAL_QUERY_PROCEDURE_NAME,
+			procedureName=Citizen.DATABASE_STORED_PROCEDURE_NAME,
+			resultSetMappings={
+					City.MAPPING_AS_ENTITY,
+					Citizen.MAPPING_AS_ARRAY,
+					City.MAPPING_AS_ARRAY})
+}) 
+@SqlResultSetMapping(
+	name=Citizen.MAPPING_AS_ARRAY,
+	columns={@ColumnResult(name="NAME", type=String.class), 
+			 @ColumnResult(name="AGE", type=int.class), 
+			 @ColumnResult(name="CITY_NAME", type=City.class)
+		}
+	)
+
+@Entity
+public class Citizen {
+	public static final String LOGICAL_QUERY_PROCEDURE_NAME   = "Citizen.NamedStoredProcedureQueryName";
+	public static final String DATABASE_STORED_PROCEDURE_NAME = "UpdatePopulationWithMultipleResult";
+	public static final String MAPPING_AS_ARRAY               = "Citizen.MappingAsArray";
+
+	@Id
+	private String name;
+	private int age;
+	
+	@ManyToOne
+	private City city;
+	
+	public Citizen(String name, int age, City city) {
+		this.name = name;
+		this.age  = age;
+		this.city = city;
+	}
+	
+	public Citizen(String name, int age) {
+		
+	}
+	
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public int getAge() {
+		return age;
+	}
+	public void setAge(int age) {
+		this.age = age;
+	}
+	public City getCity() {
+		return city;
+	}
+	public void setCity(City city) {
+		this.city = city;
+	}
+	
+	public String toString() {
+		return name + ":" + age + " lives in " + city;
+	}
+}

Propchange: openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/Citizen.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/City.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/City.java?rev=1482077&view=auto
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/City.java (added)
+++ openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/City.java Mon May 13 20:14:59 2013
@@ -0,0 +1,78 @@
+/*
+ * 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.jdbc.mapping;
+
+import javax.persistence.ColumnResult;
+import javax.persistence.Entity;
+import javax.persistence.EntityResult;
+import javax.persistence.Id;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.SqlResultSetMappings;
+
+@SqlResultSetMappings({
+	@SqlResultSetMapping(
+			name=City.MAPPING_AS_ENTITY,
+			entities={@EntityResult(entityClass=City.class)}),
+	@SqlResultSetMapping(
+			name=City.MAPPING_AS_ARRAY,
+			columns={@ColumnResult(name="CITY_NAME", type=String.class), 
+					 @ColumnResult(name="POPULATION", type=int.class)})
+})
+
+@Entity
+public class City implements Comparable<City> {
+	public static final String MAPPING_AS_ENTITY  = "City.MappedAsEntity";
+	public static final String MAPPING_AS_ARRAY   = "City.MappedAsArray";
+	@Id
+	private String name;
+	int population;
+	
+	public City() {
+		this("");
+	}
+	
+	public City(String name) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public int getPopulation() {
+		return population;
+	}
+	
+	public void setPopulation(int population) {
+		this.population = population;
+	}
+
+	@Override
+	public int compareTo(City o) {
+		return name.compareTo(o.name);
+	}
+	
+	public String toString() {
+		return name + ":" + population;
+	}
+}

Propchange: openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/City.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestStoredProcedure.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestStoredProcedure.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestStoredProcedure.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/mapping/TestStoredProcedure.java Mon May 13 20:14:59 2013
@@ -42,7 +42,7 @@ import org.apache.openjpa.persistence.te
  * <br>
  * This test creates a Stored Procedure named {@code MIGRATION} that returns multiple result sets.
  * <br>
- * The data for the test is stored in two simple tables {@code PERSON} and {@code CITY}.
+ * The data for the test is stored in two simple tables {@code CITIZEN} and {@code CITY}.
  * The stored procedure moves few people meeting certain criteria from one city to another. 
  * <br>
  * The data is hand crafted and hence it is possible to verify data integrity before and
@@ -55,56 +55,104 @@ import org.apache.openjpa.persistence.te
  *
  */
 public class TestStoredProcedure extends SingleEMFTestCase {
-	static String PROCEDURE = "MIGRATION";
 	public static Random rng = new Random();
 	
 	private static int AGE_THRESHOLD = 20;
-	private static final String[] CITIES = {"Los Angeles", "San Francisco", "Dallas", "Bangalore","Bombay"};
-	private static final Map<String, int[]> POPULATION = new TreeMap<String, int[]>();
+	private final City[] CITIES = {
+		new City("Los Angeles"), 
+		new City("San Francisco"), 
+		new City("Dallas"), 
+		new City("Bangalore"),
+		new City("Bombay")};
+	private final Map<City, int[]> POPULATION = new TreeMap<City, int[]>();
 	private static final int NPERSON = 100;
+	
 	public void setUp() throws Exception {
-		super.setUp(USE_SINGLETON);
-		Connection con = emf.createEntityManager().unwrap(Connection.class);
-		if (!isDefined(con, PROCEDURE)) {
-			dropTables(con, "PERSON", "CITY");
-			createTables(con);
-			loadData(con, NPERSON);
-			createProcedure(con, PROCEDURE);
+		super.setUp(CLEAR_TABLES, Citizen.class, City.class);
+		
+		for (City city : CITIES) {
+			POPULATION.put(city, new int[2]);
 		}
+		Connection con = emf.createEntityManager().unwrap(Connection.class);
+		dropProcedure(con, Citizen.DATABASE_STORED_PROCEDURE_NAME);
+		createProcedure(con, Citizen.DATABASE_STORED_PROCEDURE_NAME);
+		loadData(con, NPERSON);
 	}
 	
 	public void testStoredProcedureByDatabaseProcedureName() {
+		EntityManager em = emf.createEntityManager();
+		StoredProcedureQuery spq = em.createStoredProcedureQuery(Citizen.DATABASE_STORED_PROCEDURE_NAME);
+		executeAndVerify(em, spq);
+	}
+	
+	public void testStoredProcedureByLogicalName() {
+		EntityManager em = emf.createEntityManager();
+		StoredProcedureQuery spq = em.createNamedStoredProcedureQuery(Citizen.LOGICAL_QUERY_PROCEDURE_NAME);
+		executeAndVerify(em, spq);
+	}
+
+	public void executeAndVerify(EntityManager em, StoredProcedureQuery spq) {
 		if (getDBDictionary() instanceof MySQLDictionary == false) {
 			System.err.println("*** Skipping test " + this.getClass().getName() + ". Runs only with MySQL");
 			return;
 		}
-		EntityManager em = emf.createEntityManager();
-		StoredProcedureQuery spq = em.createStoredProcedureQuery(PROCEDURE);
-		spq.setParameter(1, AGE_THRESHOLD);
-		spq.setParameter(2, CITIES[0]);
-		spq.setParameter(3, CITIES[1]);
-		spq.setParameter(4, NPERSON);
-
+		City origin = CITIES[0];
+		City destination = CITIES[1];
+		
+		setParameters(spq, AGE_THRESHOLD, origin.getName(), destination.getName(), NPERSON);
+		
 		assertTrue(spq.execute());
-		int rsCount = 0;
-		List<?> result = spq.getResultList();
-		System.err.println("Result Set " + (++rsCount));
-		print(result);
-		while (spq.hasMoreResults()) {
-			System.err.println("Result Set " + (++rsCount));
-			print(spq.getResultList());
-		}
-		assertEquals(3, rsCount);
 		
-		System.err.println("Update Count = " + spq.getUpdateCount());
-		Set<Parameter<?>> params = spq.getParameters();
-		for (Parameter<?> p : params) {
-			System.err.println(p);
+		List<?> populationBeforeMove = spq.getResultList();
+		print("City Population before movement", populationBeforeMove);
+		
+		assertTrue(spq.hasMoreResults());
+		List<?> peopleMoved = spq.getResultList();
+		print("People who moved", peopleMoved);
+		
+		assertTrue(spq.hasMoreResults());
+		List<?> populationAfterMove = spq.getResultList();
+		print("City Population after movement", populationAfterMove);
+		
+		assertFalse(spq.hasMoreResults());
+		
+		int updateCount = spq.getUpdateCount();
+		assertEquals(updateCount, CITIES.length);
+		
+		origin = em.find(City.class, origin.getName());
+		em.refresh(origin);
+		destination = em.find(City.class, destination.getName());
+		em.refresh(destination);
+		
+		assertEquals(getPopulation(POPULATION, origin) - peopleMoved.size(), origin.getPopulation());
+		assertEquals(getPopulation(POPULATION, destination) + peopleMoved.size(), destination.getPopulation());
+	}
+	
+	
+	void setParameters(StoredProcedureQuery q, Object...params) {
+		if (params == null) return;
+		for (int i = 0; i < params.length; i++) {
+			q.setParameter(i+1, params[i]);
 		}
 	}
 	
-	void print(List<?> result) {
+	int getPopulation(Map<City,int[]> pop, City city) {
+		if (!pop.containsKey(city))
+			fail(city + " does not exist");
+		int[] pops = pop.get(city);
+		return pops[0]+pops[1];
+	}
+
+	/**
+	 * Print the result of the given list.
+	 * Verifiies that we can iterate over the result and have no null element.
+	 * @param header
+	 * @param result
+	 */
+	void print(String header, List<?> result) {
+		System.err.println(header);
 		for (Object row : result) {
+			assertNotNull(row);
 			if (row.getClass().isArray()) {
 				System.err.println(Arrays.toString((Object[])row));
 			} else {
@@ -133,19 +181,19 @@ public class TestStoredProcedure extends
               // Result Set #1: All the cities with current population count
               + "SELECT c.NAME,c.POPULATION FROM CITY c; "
               // ResultSet #2: select persons who will be moved
-              + "SELECT p.NAME,p.AGE, c.NAME " 
-              + "   FROM PERSON p JOIN CITY c "
-              + "   WHERE p.CITY=c.NAME AND p.AGE < A AND c.NAME=C1 AND c.POPULATION < M;" 
+              + "SELECT p.NAME,p.AGE, c.NAME AS CITY_NAME" 
+              + "   FROM CITIZEN p JOIN CITY c "
+              + "   WHERE p.CITY_NAME=c.NAME AND p.AGE < A AND c.NAME=C1 AND c.POPULATION < M;" 
               + "SELECT COUNT(*) INTO T " 
-              + "   FROM PERSON p JOIN CITY c "
-              + "   WHERE p.CITY=c.NAME AND p.AGE < A AND c.NAME=C1 AND c.POPULATION < M;" 
+              + "   FROM CITIZEN p JOIN CITY c "
+              + "   WHERE p.CITY_NAME=c.NAME AND p.AGE < A AND c.NAME=C1 AND c.POPULATION < M;" 
               // Update those persons' to their new city
-              + "UPDATE PERSON p SET p.CITY=C2 WHERE p.CITY=C1 AND p.AGE < A;"
-              + "SELECT p.CITY, COUNT(p.CITY) from PERSON p GROUP BY p.CITY;"
+              + "UPDATE CITIZEN p SET p.CITY_NAME=C2 WHERE p.CITY_NAME=C1 AND p.AGE < A;"
+              + "SELECT p.CITY_NAME, COUNT(p.CITY_NAME) AS POPULATION from CITIZEN p GROUP BY p.CITY_NAME;"
               // Update population of all the cities
-              + "UPDATE CITY c SET c.POPULATION=(SELECT COUNT(*) FROM PERSON p WHERE p.CITY=c.NAME);"
+              + "UPDATE CITY c SET c.POPULATION=(SELECT COUNT(*) FROM CITIZEN p WHERE p.CITY_NAME=c.NAME);"
               + "END";
-		
+		boolean autoCommit = con.getAutoCommit();
 		try {
 			con.setAutoCommit(false);
 			CallableStatement stmt = con.prepareCall(createSQL);
@@ -154,6 +202,7 @@ public class TestStoredProcedure extends
 			System.err.println(e.getMessage());
 		} finally {
 			con.commit();
+			con.setAutoCommit(autoCommit);
 		}
 	}
 	
@@ -174,61 +223,42 @@ public class TestStoredProcedure extends
 			return false;
 		}
 	}
-	public void createTables(Connection con) throws SQLException {
-		String createTable = "CREATE TABLE IF NOT EXISTS PERSON (" 
-			               + "NAME VARCHAR(20) PRIMARY KEY, AGE INT, CITY VARCHAR(20));";
-		
-		CallableStatement stmt = con.prepareCall(createTable);
-		stmt.execute();
-		
-		createTable  = "CREATE TABLE IF NOT EXISTS CITY (" 
-            + "NAME VARCHAR(20) PRIMARY KEY, POPULATION INT);";
-		stmt.execute(createTable);
-	}
-	
-	public void dropTables(Connection con, String... tables) throws SQLException {
-		for (String table : tables) {
-			String dropTable = "DROP TABLE IF EXISTS " + table;
-			CallableStatement stmt = con.prepareCall(dropTable);
-			stmt.execute();
-		}
-	}
-	
+
 	public void loadData(Connection con, int P) throws SQLException {
 		// Insert cities with 0 populations 
-		// Insert PEOPLE into Random cities with trandom age
-		PreparedStatement stmt = con.prepareStatement("INSERT INTO PERSON VALUES (?,?,?)");
+		// Insert PEOPLE into Random cities with random age
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		for (City city : CITIES) {
+			em.persist(city);
+		}
 		for (int i = 0; i < P; i++) {
 			int age = rng.nextInt(100);
-			String city = CITIES[rng.nextInt(CITIES.length)];
+			City city = CITIES[rng.nextInt(CITIES.length)];
 			int[] pop = POPULATION.get(city);
-			if (pop == null) pop = new int[2];
+			assertNotNull(pop);
 			pop[age > AGE_THRESHOLD ? 1 : 0]++;
 			POPULATION.put(city, pop);
 
-			stmt.setString(1, "Person"+i);
-			stmt.setInt(2, age);
-			stmt.setString(3, city);
-			stmt.addBatch();
+			Citizen citizen = new Citizen("Citizen"+i, age, city);
+			em.persist(citizen);
 		}
-		stmt.executeBatch();
-		stmt.clearBatch();
+		for (City city : CITIES) {
+			int[] pops = POPULATION.get(city);
+			city.setPopulation(pops[0] + pops[1]);
+		}		
+		em.getTransaction().commit();
 		 
-		stmt = con.prepareStatement("INSERT INTO CITY VALUES (?,?)");
-		System.err.println("Populated database with " + NPERSON + " persons in " + CITIES.length + "cities");
+		System.err.println("Populated database with " + NPERSON + " persons in " + CITIES.length + " cities");
 		System.err.println("[City]   [Age <" + AGE_THRESHOLD + "] + [Age >= " + AGE_THRESHOLD + "] = TOTAL");
 		
-		for (Map.Entry<String, int[]> e : POPULATION.entrySet()) {
-			String city = e.getKey();
-			int[]  pop  = e.getValue();
-			System.err.println(city + " " + pop[0] + "+" + pop[1] + " = " + (pop[0]+pop[1]));
-			
-			stmt.setString(1, city);
-			stmt.setInt(2,    pop[0]+pop[1]);
-			stmt.addBatch();
+		List<City> cities = em.createQuery("select c from City c", City.class).getResultList();
+		assertEquals(CITIES.length, cities.size());
+		for (City city : cities) {
+			int[] pop = POPULATION.get(city);
+			assertEquals(city.getPopulation(), pop[0] + pop[1]);
+			System.err.println(city.getName() + " " + pop[0] + "+" + pop[1] + " = " + city.getPopulation());
 		}
-		stmt.executeBatch();
-		stmt.clearBatch();
 	}
 
 }

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AbstractQuery.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AbstractQuery.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AbstractQuery.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AbstractQuery.java Mon May 13 20:14:59 2013
@@ -75,7 +75,7 @@ public abstract class AbstractQuery<X> i
     private static final Localizer _loc = Localizer.forPackage(AbstractQuery.class);
 
     protected boolean _relaxBindParameterTypeChecking;
-    protected boolean _convertPositionalParams;
+    protected final boolean _convertPositionalParams;
 
     // Will be null if this isn't a NamedQuery
     protected final QueryMetaData _qmd;
@@ -84,18 +84,25 @@ public abstract class AbstractQuery<X> i
 
     protected Map<Parameter<?>, Object> _boundParams;
     protected Map<Object, Parameter<?>> _declaredParams;
-
-    public AbstractQuery(QueryMetaData qmd, EntityManagerImpl em) {
+    private final String _language;
+    
+    public AbstractQuery(QueryMetaData qmd, EntityManagerImpl em, String language) {
         _qmd = qmd;
         _em = em;
-
+        _language = language;
+        _convertPositionalParams = em.getConvertPositionalParametersToNamed() && !isNative();
         _boundParams = new HashMap<Parameter<?>, Object>();
     }
 
-    public boolean isNative() {
-        return QueryLanguages.LANG_SQL.equals(getLanguage()) 
-            || QueryLanguages.LANG_STORED_PROC.equals(getLanguage());
+    public final boolean isNative() {
+        return QueryLanguages.LANG_SQL.equals(_language) 
+            || QueryLanguages.LANG_STORED_PROC.equals(_language);
+    }
+    
+    public final String getLanguage() {
+    	return _language;
     }
+    
 
     protected abstract void assertOpen();
 
@@ -407,6 +414,14 @@ public abstract class AbstractQuery<X> i
                 if (name.equals(e.getName()))
                     return e;
             }
+            if (_convertPositionalParams && name.startsWith("_")) {
+            	String newName =  name.substring(1);
+            	Set<Integer> integerKeys = getDeclaredParameterKeys(Integer.class);
+                for (Integer i : integerKeys) {
+                    if (newName.equals(String.valueOf(i)))
+                        return _declaredParams.get(i);
+                }
+            }
             throw new IllegalArgumentException(_loc.get("param-missing-name", name, getQueryString(),
                 getDeclaredParameterKeys()).getMessage());
         }
@@ -424,7 +439,7 @@ public abstract class AbstractQuery<X> i
      *             if the parameter with the given position does not exist
      */
     public Parameter<?> getParameter(int pos) {
-        if (_convertPositionalParams == true) {
+        if (_convertPositionalParams) {
             return getParameter("_" + String.valueOf(pos));
         }
         Parameter<?> param = getDeclaredParameters().get(pos);

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java Mon May 13 20:14:59 2013
@@ -162,10 +162,10 @@ import org.apache.openjpa.meta.Lifecycle
 import org.apache.openjpa.meta.MetaDataFactory;
 import org.apache.openjpa.meta.MetaDataModes;
 import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.meta.MultiQueryMetaData;
 import org.apache.openjpa.meta.Order;
 import org.apache.openjpa.meta.QueryMetaData;
 import org.apache.openjpa.meta.SequenceMetaData;
-import org.apache.openjpa.meta.MultiQueryMetaData;
 import org.apache.openjpa.meta.UpdateStrategies;
 import org.apache.openjpa.meta.ValueMetaData;
 import org.apache.openjpa.meta.ValueStrategies;
@@ -457,8 +457,6 @@ public class AnnotationPersistenceMetaDa
 
         MetaDataTag tag;
         for (Annotation anno : pkg.getDeclaredAnnotations()) {
-            System.err.println("parsePackageAnnotations( " + _cls.getName() + ") : " 
-            		+ anno.annotationType().getClass().getSimpleName());
             tag = _tags.get(anno.annotationType());
             if (tag == null) {
                 handleUnknownPackageAnnotation(pkg, anno);
@@ -583,8 +581,6 @@ public class AnnotationPersistenceMetaDa
         Collection<LifecycleCallbacks>[] listeners = null;
         MetaDataTag tag;
         for (Annotation anno : _cls.getDeclaredAnnotations()) {
-            System.err.println("parseClassAnnotations( " + _cls.getName() + ") : " 
-            		+ anno.annotationType().getSimpleName());
             tag = _tags.get(anno.annotationType());
             if (tag == null) {
                 handleUnknownClassAnnotation(meta, anno);
@@ -1865,10 +1861,9 @@ public class AnnotationPersistenceMetaDa
             if (_log.isTraceEnabled())
                 _log.trace(_loc.get("parse-query", query.name()));
 
-            QueryMetaData meta = new QueryMetaData(_cls, query.name());
+            QueryMetaData meta = new QueryMetaData(_cls, query.name(), JPQLParser.LANG_JPQL);
             addQueryMetaData(el, meta);
             
-            meta.setLanguage(JPQLParser.LANG_JPQL);
             meta.setQueryString(query.query());
             for (QueryHint hint : query.hints())
                 meta.addHint(hint.name(), hint.value());
@@ -1896,9 +1891,9 @@ public class AnnotationPersistenceMetaDa
      */
     protected void addQueryMetaData(Object location, QueryMetaData meta) {
     	QueryMetaData existing = getRepository().addQueryMetaData(meta);
-    	if (existing != null) {
+    	if (existing != null && existing.getDefiningType() != meta.getDefiningType()) {
     		Class<?> scope = existing.getDefiningType();
-    		throw new UserException(_loc.get("dup-query", meta.getName(), location, scope));
+    		_log.warn(_loc.get("dup-query", meta.getName(), location, scope));
     	}
     }
 
@@ -1967,11 +1962,10 @@ public class AnnotationPersistenceMetaDa
             if (_log.isTraceEnabled())
                 _log.trace(_loc.get("parse-native-query", query.name()));
 
-            QueryMetaData meta = new QueryMetaData(_cls, query.name());
+            QueryMetaData meta = new QueryMetaData(_cls, query.name(), QueryLanguages.LANG_SQL);
             addQueryMetaData(el, meta);
             
-            meta.setLanguage(QueryLanguages.LANG_SQL);
-            meta.setQueryString(query.query());
+           meta.setQueryString(query.query());
             Class<?> res = query.resultClass();
             if (ImplHelper.isManagedType(getConfiguration(), res))
                 meta.setCandidateType(res);

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java Mon May 13 20:14:59 2013
@@ -86,9 +86,9 @@ import org.apache.openjpa.lib.util.Local
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.meta.MultiQueryMetaData;
 import org.apache.openjpa.meta.QueryMetaData;
 import org.apache.openjpa.meta.SequenceMetaData;
-import org.apache.openjpa.meta.MultiQueryMetaData;
 import org.apache.openjpa.persistence.criteria.CriteriaBuilderImpl;
 import org.apache.openjpa.persistence.criteria.CriteriaDeleteImpl;
 import org.apache.openjpa.persistence.criteria.CriteriaUpdateImpl;
@@ -1004,7 +1004,8 @@ public class EntityManagerImpl
     public OpenJPAQuery createQuery(String language, String query) {
         assertNotCloseInvoked();
         try {
-            // We need
+            // We need to covert the JPQL string if we are converting positional parameters
+        	// as named parameter
             if (query != null && _convertPositionalParams && JPQLParser.LANG_JPQL.equals(language)) {
                 query = query.replaceAll("[\\?]", "\\:_");
             }
@@ -1045,11 +1046,15 @@ public class EntityManagerImpl
         try {
             QueryMetaData meta = _broker.getConfiguration().
                 getMetaDataRepositoryInstance().getQueryMetaData(null, name, _broker.getClassLoader(), true);
-            String qid = meta.getQueryString();
-            
+            String query = meta.getQueryString();
+            String language = meta.getLanguage();
+            if (query != null && _convertPositionalParams && JPQLParser.LANG_JPQL.equals(language)) {
+                query = query.replaceAll("[\\?]", "\\:_");
+            }
+            String qid = query;
             PreparedQuery pq = JPQLParser.LANG_JPQL.equals(meta.getLanguage()) ? getPreparedQuery(qid) : null;
-            org.apache.openjpa.kernel.Query del =
-                (pq == null || !pq.isInitialized()) ? _broker.newQuery(meta.getLanguage(), meta.getQueryString())
+            org.apache.openjpa.kernel.Query del = (pq == null || !pq.isInitialized()) 
+                    ? _broker.newQuery(language, query)
                     : _broker.newQuery(pq.getLanguage(), pq);
             
             meta.setInto(del);
@@ -1973,16 +1978,6 @@ public class EntityManagerImpl
 	 * The details about the Stored Procedure is specified in a {@link NamedStoredProcedureQuery} annotation
 	 * or its equivalent XML descriptor. The input argument is the name attribute of that annotation.
 	 * <br>
-	 * Construction of a {@link StoredProcedureQuery} object is a three step process
-	 * <LI>a corresponding SQL {@code S} (e.g. {@code "call <procedure>(?,?...)"}) is formed. 
-	 * The number of parameter argument in the {@coe call} statement
-	 * is deternmined by the parameters declared in {@link NamedStoredProcedureQuery#parameters()} annotation.
-	 * <LI>a {@link org.apache.openjpa.kernel.Query kernel query} {@code kQ} is created for 
-	 * {@link QueryLanguages#LANG_SQL SQL} language with the string {@code S} 
-	 * <LI>a {@link QueryImpl facade query} {@code fQ} is created that delegates to the kernel query {@code kQ}
-	 * <LI>a {@link StoredProcedureQueryImpl stored procedure query} is created that delegates to the facade query
-	 * {@code fQ}. 
-	 * <br>
 	 * A {@link NamedStoredProcedureQuery named Stored Procedure Query} also may specify how its results be mapped.
 	 * A {@link QueryResultMapping query result mapping} is implicitly associated. It is implicit as opposed to
 	 * other {@link QueryResultMapping} mapping instances that are created via {@link SqlResultSetMapping} 
@@ -1992,25 +1987,11 @@ public class EntityManagerImpl
 	 */
 	@Override
 	public StoredProcedureQuery createNamedStoredProcedureQuery(String name) {
-		// TODO JPA 2.1 Method
 		QueryMetaData meta = getQueryMetadata(name);
-		if (meta instanceof MultiQueryMetaData) {
-			throw new RuntimeException(name + " is not a Stored Procedure Query");
+		if (meta instanceof MultiQueryMetaData == false) {
+			throw new RuntimeException(name + " is not an identifier for a Stored Procedure Query");
 		}
-        String procedureName = meta.getQueryString();
-        int parameterCount = ((MultiQueryMetaData)meta).getParameterCount();
-        StringBuilder sql = new StringBuilder("call ").append(procedureName).append("(");
-        for (int i = 0; i < parameterCount; i++) {
-        	sql.append("?");
-        	if (i < parameterCount-1) sql.append(",");
-        }
-        sql.append(")");
-        return sp(sql.toString(), (MultiQueryMetaData)meta, name + ".ResultSetMapping");
-//        org.apache.openjpa.kernel.Query kernelQuery = _broker.newQuery(QueryLanguages.LANG_SQL, sql.toString());
-//        kernelQuery.setResultMapping(null, name + ".ResultSetMapping");
-//        org.apache.openjpa.persistence.QueryImpl<?> facadeQuery = new QueryImpl(this, _ret, kernelQuery, meta, _log);
-//        	
-//        return new StoredProcedureQueryImpl(facadeQuery);
+        return newProcedure(((MultiQueryMetaData)meta).getProcedureName(), (MultiQueryMetaData)meta);
 	}
 
 	/**
@@ -2027,42 +2008,57 @@ public class EntityManagerImpl
 	 */
 	@Override
 	public StoredProcedureQuery createStoredProcedureQuery(String procedureName) {
-		// TODO JPA 2.1 Method
-		
-		org.apache.openjpa.kernel.Query kernelQuery = _broker.newQuery(QueryLanguages.LANG_STORED_PROC, 
-				procedureName);
-		org.apache.openjpa.persistence.QueryImpl<?> facadeQuery = new QueryImpl(this, _ret, 
-				kernelQuery, null, _log);
-		return new StoredProcedureQueryImpl(procedureName, facadeQuery);
+		return newProcedure(procedureName, null);
 	}
 
 	@Override
 	public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) {
-		// TODO JPA 2.1 Method
-		String tempName = "Temp"+System.currentTimeMillis();
-		MultiQueryMetaData meta = new MultiQueryMetaData(null, "xyz");
-		for (Class res : resultClasses) {
-			meta.addComponent().setResultType(res);
+		String tempName = "StoredProcedure-"+System.nanoTime();
+		MultiQueryMetaData meta = new MultiQueryMetaData(null, tempName, procedureName, true); 
+		for (Class<?> res : resultClasses) {
+			meta.addComponent(res);
 		}
-		return sp(procedureName, meta, tempName);
+		return newProcedure(procedureName, meta);
 	}
 
 	@Override
 	public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings) {
 		// TODO JPA 2.1 Method
-		String tempName = "Temp"+System.currentTimeMillis();
-		MultiQueryMetaData meta = new MultiQueryMetaData(null, "xyz");
+		String tempName = "StoredProcedure-"+System.nanoTime();
+		MultiQueryMetaData meta = new MultiQueryMetaData(null, tempName, procedureName, true);
 		for (String mapping : resultSetMappings) {
-			meta.addComponent().setResultSetMappingName(mapping);
+			meta.addComponent(mapping);
 		}
-		return sp(procedureName, meta, tempName);
+		return newProcedure(procedureName, meta);
 	}
 	
-	private StoredProcedureQuery sp(String sql, MultiQueryMetaData meta, String mappingName) {
-        org.apache.openjpa.kernel.Query kernelQuery = _broker.newQuery(QueryLanguages.LANG_STORED_PROC, sql);
-        kernelQuery.setResultMapping(null, mappingName);
+	/**
+	 * Creates a query to execute a Stored Procedure.
+	 * <br>
+	 * Construction of a {@link StoredProcedureQuery} object is a three step process
+	 * <LI>
+	 * <LI>a {@link org.apache.openjpa.kernel.Query kernel query} {@code kQ} is created for 
+	 * {@link QueryLanguages#LANG_SQL SQL} language with the string {@code S} 
+	 * <LI>a {@link QueryImpl facade query} {@code fQ} is created that delegates to the kernel query {@code kQ}
+	 * <LI>a {@link StoredProcedureQueryImpl stored procedure query} is created that delegates to the facade query
+	 * {@code fQ}. 
+	 * <br>
+	 * 
+	 * @param sql name of the database stored procedure. 
+	 * @param meta
+	 * @param mappingName
+	 * @return
+	 */
+	private StoredProcedureQuery newProcedure(String procedureName, MultiQueryMetaData meta) {
+        org.apache.openjpa.kernel.QueryImpl kernelQuery = (org.apache.openjpa.kernel.QueryImpl)
+        	_broker.newQuery(QueryLanguages.LANG_STORED_PROC, procedureName);
+        kernelQuery.getStoreQuery().setQuery(meta);
+        if (meta != null) {
+    		getConfiguration().getMetaDataRepositoryInstance().addQueryMetaData(meta);
+        	kernelQuery.setResultMapping(null, meta.getResultSetMappingName());
+        }
         org.apache.openjpa.persistence.QueryImpl<?> facadeQuery = new QueryImpl(this, _ret, kernelQuery, meta, _log);
-        return new StoredProcedureQueryImpl(sql, facadeQuery);
+        return new StoredProcedureQueryImpl(procedureName, facadeQuery);
 	}
 
 	@Override
@@ -2105,9 +2101,14 @@ public class EntityManagerImpl
 		MetaDataRepository repos = _broker.getConfiguration().getMetaDataRepositoryInstance();
         QueryMetaData meta = repos.getQueryMetaData(null, name, _broker.getClassLoader(), true);
 	    if (meta == null) {
-	    	throw new RuntimeException("No stored procedure query named [" + name + "]");
+	    	throw new RuntimeException("No query named [" + name + "]");
 	    }
 	    return meta;
 	}
+	
+	public boolean getConvertPositionalParametersToNamed() {
+		return _convertPositionalParams;
+	}
+	
 
 }

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java Mon May 13 20:14:59 2013
@@ -21,17 +21,10 @@ package org.apache.openjpa.persistence;
 import static org.apache.openjpa.kernel.QueryLanguages.LANG_PREPARED_SQL;
 
 import java.io.Serializable;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -39,20 +32,15 @@ import javax.persistence.FlushModeType;
 import javax.persistence.LockModeType;
 import javax.persistence.NoResultException;
 import javax.persistence.NonUniqueResultException;
-import javax.persistence.Parameter;
 import javax.persistence.Query;
-import javax.persistence.TemporalType;
 import javax.persistence.TypedQuery;
-import javax.persistence.criteria.ParameterExpression;
 
-import org.apache.openjpa.conf.Compatibility;
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.kernel.Broker;
 import org.apache.openjpa.kernel.DelegatingQuery;
 import org.apache.openjpa.kernel.DelegatingResultList;
 import org.apache.openjpa.kernel.DistinctResultList;
 import org.apache.openjpa.kernel.FetchConfiguration;
-import org.apache.openjpa.kernel.Filters;
 import org.apache.openjpa.kernel.PreparedQuery;
 import org.apache.openjpa.kernel.PreparedQueryCache;
 import org.apache.openjpa.kernel.QueryHints;
@@ -100,15 +88,9 @@ public class QueryImpl<X> extends Abstra
 	 */
     public QueryImpl(EntityManagerImpl em, RuntimeExceptionTranslator ret, 
     		org.apache.openjpa.kernel.Query query, QueryMetaData qmd, Log log) {
-        super(qmd, em);
+        super(qmd, em, query.getLanguage());
         _query = new DelegatingQuery(query, ret);
         _lock = new ReentrantLock();
-        if (query.getLanguage() == QueryLanguages.LANG_SQL) { 
-            _convertPositionalParams = false; 
-        } else { 
-            Compatibility compat  = query.getStoreContext().getConfiguration().getCompatibilityInstance(); 
-            _convertPositionalParams = compat.getConvertPositionalParametersToNamed();    
-        }
         _log = log;
     }
 
@@ -142,9 +124,6 @@ public class QueryImpl<X> extends Abstra
 		return _em;
 	}
 
-	public String getLanguage() {
-		return _query.getLanguage();
-	}
 
 	public QueryOperationType getOperation() {
         return QueryOperationType.fromKernelConstant(_query.getOperation());

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java Mon May 13 20:14:59 2013
@@ -53,26 +53,53 @@ import org.apache.openjpa.util.UserExcep
  * @author Pinaki Poddar
  *
  */
-public class StoredProcedureQueryImpl<X> implements StoredProcedureQuery {
+public class StoredProcedureQueryImpl implements StoredProcedureQuery {
 	final String _name;
-	final AbstractQuery<?> _delegate;
+	final QueryImpl<?> _delegate;
 	QueryResultCallback    _callback;
 	
-	public StoredProcedureQueryImpl(String name, AbstractQuery<?> delegate) {
-		_name = name;
+	/**
+	 * Construct a query for executing a Stored Procedure.
+	 * 
+	 * @param name name of the database stored procedure.
+	 * @param delegate the delegate which manages bind parameters on behalf of this
+	 * query.
+	 */
+	public StoredProcedureQueryImpl(String procedureName, QueryImpl<?> delegate) {
+		_name     = procedureName;
+		if (!isValidProcedureName(procedureName)) {
+			throw new RuntimeException(procedureName + " is not a valid procedure name");
+		}
 		_delegate = delegate;
 		_delegate.compile();
 	}
 	
+	/**
+	 * Gets the facade delegate that manages bind parameters on behalf of this receiver.  
+	 * @return
+	 */
 	public OpenJPAQuery<?> getDelegate() {
 		return _delegate;
 	}
+	
+	/**
+	 * Gets the kernel delegate that is handles actual execution on behalf of this receiver.   
+	 * @return
+	 */
+	public org.apache.openjpa.kernel.Query getExecutableQuery() {
+		return _delegate.getDelegate();
+	}
 
+	/**
+	 * Executes this receiver by delegation to the underlying executable query.
+	 * <br>
+	 * This method is multi-call safe. The underlying executable query is executed
+	 * <em>only</em> for the first invocation. Subsequent 
+	 */
 	@Override
 	public boolean execute() {
 		if (_callback == null) {
-			_callback = (QueryResultCallback)((QueryImpl<?>)_delegate).getDelegate()
-						.execute(_delegate.getParameterValues());
+			_callback = (QueryResultCallback) getExecutableQuery().execute(_delegate.getParameterValues());
 		}
 		return _callback.getExecutionResult();
 	}
@@ -335,6 +362,19 @@ public class StoredProcedureQueryImpl<X>
 		}
 	}
 	
+	boolean isValidProcedureName(String s) {
+		if (s == null || s.trim().length() == 0) {
+			return false;
+		}
+		for (int i = 0; i < s.length(); i++) {
+			char ch = s.charAt(i);
+			if (ch == '#' || ch == '$' || Character.isJavaIdentifierPart(ch)) 
+				continue;
+			return false;
+		}
+		return true;
+	}
+	
 	public String toString() {
 		return _name;
 	}

Modified: openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java?rev=1482077&r1=1482076&r2=1482077&view=diff
==============================================================================
--- openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java (original)
+++ openjpa/sandboxes/21/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java Mon May 13 20:14:59 2013
@@ -1830,9 +1830,8 @@ public class XMLPersistenceMetaDataParse
         if (log.isTraceEnabled())
             log.trace(_loc.get("parse-query", name));
 
-        QueryMetaData meta = new QueryMetaData(_cls, name);
+        QueryMetaData meta = new QueryMetaData(_cls, name, JPQLParser.LANG_JPQL);
 
-        meta.setLanguage(JPQLParser.LANG_JPQL);
         meta.setQueryString(attrs.getValue("query"));
         String lockModeStr = attrs.getValue("lock-mode");
         LockModeType lmt = processNamedQueryLockModeType(log, lockModeStr, name);
@@ -1951,9 +1950,8 @@ public class XMLPersistenceMetaDataParse
             log.warn(_loc.get("override-query", name, currentLocation()));
         }
 
-        meta = new QueryMetaData(_cls, name); 
+        meta = new QueryMetaData(_cls, name, QueryLanguages.LANG_SQL); 
         getRepository().addQueryMetaData(meta);
-        meta.setLanguage(QueryLanguages.LANG_SQL);
         meta.setQueryString(attrs.getValue("query"));
         String val = attrs.getValue("result-class");
         if (val != null) {