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) {