Author: rmannibucau Date: Sun Jun 7 18:12:39 2015 New Revision: 1684055 URL: http://svn.apache.org/r1684055 Log: mapping db param to jpa param for stored procedure parameter names + starting to impl cursor support (need testing)
Modified: openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java openjpa/branches/openjpa_jpa-2.1/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/TestStoredProcedure.java openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/entity/EntityWithStoredProcedure.java openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java Modified: openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java URL: http://svn.apache.org/viewvc/openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java?rev=1684055&r1=1684054&r2=1684055&view=diff ============================================================================== --- openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java (original) +++ openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/StoredProcedureQuery.java Sun Jun 7 18:12:39 2015 @@ -37,7 +37,7 @@ import java.sql.CallableStatement; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -105,7 +105,7 @@ public class StoredProcedureQuery extend } } } - return new StoredProcedureQueryExecutor(this, mappings, classes); + return new StoredProcedureQueryExecutor(this, mappings, classes, _meta); } public boolean supportsParameterDeclarations() { @@ -128,9 +128,11 @@ public class StoredProcedureQuery extend public class StoredProcedureQueryExecutor extends AbstractExecutor { private final List<Class<?>> _resultClasses; private final List<QueryResultMapping> _resultMappings; + private final Map<String, String> _parametersNameMapping = new HashMap<String, String>(); + private final Map<String, String> _parametersNameMappingReverse = new HashMap<String, String>(); public StoredProcedureQueryExecutor(StoredProcedureQuery q, List<QueryResultMapping> resultMapping, - List<Class<?>> classes) { + List<Class<?>> classes, MultiQueryMetaData _meta) { QueryContext ctx = q.getContext(); _resultMappings = resultMapping; _resultClasses = classes; @@ -140,6 +142,14 @@ public class StoredProcedureQuery extend if (_proc == null) { throw new RuntimeException("Can not find stored procedure " + procName); } + for (final Column c : _proc.getColumns()) { + final String name = _meta.getParameters().get(c.getIndex()).getName(); + if (name != null) { + final String dbName = c.getIdentifier().getName(); + _parametersNameMapping.put(name, dbName); + _parametersNameMappingReverse.put(dbName, name); + } + } } StoredProcedure getStoredProcedure(Connection conn, DBDictionary dict, String procedureName) { @@ -167,21 +177,26 @@ public class StoredProcedureQuery extend Connection conn = _store.getConnection(); CallableStatement stmnt = conn.prepareCall(_proc.getCallSQL()); - final StoredProcedureQuery spq = StoredProcedureQuery.class.cast(q); - for (Column c : spq.getProcedure().getInColumns()) { - dict.setUnknown(stmnt, c.getIndex() + 1, params[c.getIndex()], c); - } - for (Column c : spq.getProcedure().getInOutColumns()) { - final int index = c.getIndex() + 1; - stmnt.registerOutParameter(index, c.getType()); - dict.setUnknown(stmnt, index, params[index - 1], c); - } - for (Column c : spq.getProcedure().getOutColumns()) { - stmnt.registerOutParameter(c.getIndex() + 1, c.getType()); + Column[] columns = StoredProcedureQuery.class.cast(q).getProcedure().getColumns(); + for (final MultiQueryMetaData.Parameter p : _meta.getParameters()) { + final Column column = columns[p.getPosition()]; + switch (p.getMode()) { + case IN: + dict.setUnknown(stmnt, p.getPosition() + 1, params[p.getPosition()], column); + break; + case INOUT: // dont break to get the out part as well + dict.setUnknown(stmnt, p.getPosition() + 1, params[p.getPosition()], column); + case OUT: + case CURSOR: + final int index = p.getPosition() + 1; + stmnt.registerOutParameter(index, column.getType()); + } } JDBCFetchConfiguration fetch = (JDBCFetchConfiguration)q.getContext().getFetchConfiguration(); - ResultObjectProvider rop = new XROP(_resultMappings, _resultClasses, _store, fetch, stmnt); + ResultObjectProvider rop = new XROP( + _resultMappings, _resultClasses, _parametersNameMapping, + _store, fetch, stmnt); rop.open(); return rop; } catch (Exception e) { @@ -199,7 +214,7 @@ public class StoredProcedureQuery extend storedProcedureQuery.getProcedure().getInColumns(), storedProcedureQuery.getProcedure().getInOutColumns())) { for (Column c : columns) { - array[i] = userParams.get(c.getIdentifier().getName()); + array[i] = userParams.get(_parametersNameMappingReverse.get(c.getIdentifier().getName())); if (array[i++] == null) { userParams.get(c.getIndex()); } Modified: openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java URL: http://svn.apache.org/viewvc/openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java?rev=1684055&r1=1684054&r2=1684055&view=diff ============================================================================== --- openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java (original) +++ openjpa/branches/openjpa_jpa-2.1/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/XROP.java Sun Jun 7 18:12:39 2015 @@ -29,6 +29,7 @@ import java.sql.CallableStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; +import java.util.Map; /** * Gets multiple Result Object Providers each with different mapping. @@ -41,16 +42,18 @@ public class XROP implements BatchedResu private final JDBCFetchConfiguration fetch; private final List<QueryResultMapping> _multi; private final List<Class<?>> _resultClasses; + private final Map<String, String> _nameMapping; private int index; private final JDBCStore store; // Result of first execution private boolean executionResult; public XROP(List<QueryResultMapping> mappings, List<Class<?>> classes, - JDBCStore store, JDBCFetchConfiguration fetch, + Map<String, String> _parametersNameMapping, JDBCStore store, JDBCFetchConfiguration fetch, CallableStatement stmt) { _multi = mappings; _resultClasses = classes; + _nameMapping = _parametersNameMapping; this.stmt = stmt; this.fetch = fetch; this.store = store; @@ -87,6 +90,10 @@ public class XROP implements BatchedResu if (rs == null) return null; + return mapResultSet(rs); + } + + private ResultObjectProvider mapResultSet(final ResultSet rs) throws SQLException { ResultSetResult res = new ResultSetResult(rs, store.getDBDictionary()); res.setCloseConnection(false); res.setCloseStatement(false); @@ -150,7 +157,7 @@ public class XROP implements BatchedResu @Override public Object getOut(String name) { try { - return stmt.getObject(name); + return mapIfNeeded(stmt.getObject(_nameMapping.get(name))); } catch (SQLException e) { return null; } @@ -159,12 +166,19 @@ public class XROP implements BatchedResu @Override public Object getOut(int position) { try { - return stmt.getObject(position); + return mapIfNeeded(stmt.getObject(position)); } catch (SQLException e) { return null; } } + private Object mapIfNeeded(final Object object) throws SQLException { + if (ResultSet.class.isInstance(object)) { + return mapResultSet(ResultSet.class.cast(object)); + } + return object; + } + /** * Throws exception. */ Modified: openjpa/branches/openjpa_jpa-2.1/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java URL: http://svn.apache.org/viewvc/openjpa/branches/openjpa_jpa-2.1/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java?rev=1684055&r1=1684054&r2=1684055&view=diff ============================================================================== --- openjpa/branches/openjpa_jpa-2.1/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java (original) +++ openjpa/branches/openjpa_jpa-2.1/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MultiQueryMetaData.java Sun Jun 7 18:12:39 2015 @@ -18,11 +18,11 @@ */ package org.apache.openjpa.meta; +import org.apache.openjpa.kernel.QueryLanguages; + import java.util.ArrayList; import java.util.List; -import org.apache.openjpa.kernel.QueryLanguages; - /** @@ -153,17 +153,10 @@ public class MultiQueryMetaData extends private final Mode mode; private final int position; - public Parameter(String name, Class<?> type, Mode mode) { + public Parameter(int position, String name, Class<?> type, Mode mode) { this.name = name; this.type = type; this.mode = mode; - this.position = -1; - } - - public Parameter(int position, Class<?> type, Mode mode) { - this.name = null; - this.type = type; - this.mode = mode; this.position = position; } Modified: openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/TestStoredProcedure.java URL: http://svn.apache.org/viewvc/openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/TestStoredProcedure.java?rev=1684055&r1=1684054&r2=1684055&view=diff ============================================================================== --- openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/TestStoredProcedure.java (original) +++ openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/TestStoredProcedure.java Sun Jun 7 18:12:39 2015 @@ -58,12 +58,12 @@ public class TestStoredProcedure extends Procedures.inParamsString = null; EntityManager em = emf.createEntityManager(); - exec(em, "CREATE PROCEDURE TESTINS(some_number INTEGER,some_string VARCHAR(255)) " + + exec(em, "CREATE PROCEDURE TESTINS(SOME_NUMBER INTEGER,SOME_STRING VARCHAR(255)) " + "PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME " + "'" + Procedures.class.getName() + ".inParams'"); StoredProcedureQuery procedure = em.createNamedStoredProcedureQuery("EntityWithStoredProcedure.inParams"); - procedure.setParameter("SOME_NUMBER", 2015); - procedure.setParameter("SOME_STRING", "openjpa"); + procedure.setParameter("some_number", 2015); + procedure.setParameter("some_string", "openjpa"); assertFalse(procedure.execute()); assertEquals(2015, Procedures.inParamsInteger); assertEquals("openjpa", Procedures.inParamsString); @@ -72,7 +72,7 @@ public class TestStoredProcedure extends Procedures.inParamsInteger = -1; Procedures.inParamsString = null; StoredProcedureQuery procedure2 = em.createNamedStoredProcedureQuery("EntityWithStoredProcedure.inParams"); - procedure2.setParameter("SOME_NUMBER", 20152); + procedure2.setParameter("some_number", 20152); assertFalse(procedure2.execute()); em.close(); assertEquals(20152, Procedures.inParamsInteger); @@ -81,11 +81,11 @@ public class TestStoredProcedure extends public void testOut() { EntityManager em = emf.createEntityManager(); - exec(em, "CREATE PROCEDURE XTWO(IN some_number INTEGER,OUT x2 INTEGER) " + + exec(em, "CREATE PROCEDURE XTWO(IN SOME_NUMBER INTEGER,OUT x2 INTEGER) " + "PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME " + "'" + Procedures.class.getName() + ".x2'"); StoredProcedureQuery procedure = em.createNamedStoredProcedureQuery("EntityWithStoredProcedure.x2"); - procedure.setParameter("SOME_NUMBER", 5); + procedure.setParameter("some_number", 5); assertFalse(procedure.execute()); // assertEquals(10, procedure.getOutputParameterValue("result")); // not impl by derby assertEquals(10, procedure.getOutputParameterValue(2)); @@ -98,7 +98,7 @@ public class TestStoredProcedure extends "PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME " + "'" + Procedures.class.getName() + ".inout'"); StoredProcedureQuery procedure = em.createNamedStoredProcedureQuery("EntityWithStoredProcedure.inout"); - procedure.setParameter("P", 5); + procedure.setParameter("p", 5); assertFalse(procedure.execute()); // assertEquals(10, procedure.getOutputParameterValue("p")); // not impl by derby assertEquals(10, procedure.getOutputParameterValue(1)); Modified: openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/entity/EntityWithStoredProcedure.java URL: http://svn.apache.org/viewvc/openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/entity/EntityWithStoredProcedure.java?rev=1684055&r1=1684054&r2=1684055&view=diff ============================================================================== --- openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/entity/EntityWithStoredProcedure.java (original) +++ openjpa/branches/openjpa_jpa-2.1/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jdbc/procedure/entity/EntityWithStoredProcedure.java Sun Jun 7 18:12:39 2015 @@ -40,24 +40,22 @@ import static javax.persistence.Paramete name = "EntityWithStoredProcedure.inParams", procedureName = "TESTINS", parameters = { - @StoredProcedureParameter(name = "SOME_NUMBER", type = Integer.class), - @StoredProcedureParameter(name = "SOME_STRING", type = String.class) + @StoredProcedureParameter(name = "some_number", type = Integer.class), + @StoredProcedureParameter(name = "some_string", type = String.class) } ), @NamedStoredProcedureQuery( name = "EntityWithStoredProcedure.x2", procedureName = "XTWO", parameters = { - @StoredProcedureParameter(name = "SOME_NUMBER", type = Integer.class), - @StoredProcedureParameter(name = "RESULT", type = Integer.class, mode = OUT) + @StoredProcedureParameter(name = "some_number", type = Integer.class), + @StoredProcedureParameter(name = "result", type = Integer.class, mode = OUT) } ), @NamedStoredProcedureQuery( name = "EntityWithStoredProcedure.inout", procedureName = "XINOUT", - parameters = { - @StoredProcedureParameter(name = "P ", type = Integer.class, mode = INOUT) - } + parameters = @StoredProcedureParameter(name = "p", type = Integer.class, mode = INOUT) ), @NamedStoredProcedureQuery( name = "EntityWithStoredProcedure.mapping", Modified: openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java URL: http://svn.apache.org/viewvc/openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=1684055&r1=1684054&r2=1684055&view=diff ============================================================================== --- openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java (original) +++ openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java Sun Jun 7 18:12:39 2015 @@ -2216,6 +2216,7 @@ public class AnnotationPersistenceMetaDa StoredProcedureParameter[] params = proc.parameters(); for (StoredProcedureParameter param : params) { MultiQueryMetaData.Parameter p = new MultiQueryMetaData.Parameter( + meta.getParameterCount(), param.name(), param.type(), toKernelParameterMode(param.mode())); meta.registerParameter(p); } Modified: openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java URL: http://svn.apache.org/viewvc/openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java?rev=1684055&r1=1684054&r2=1684055&view=diff ============================================================================== --- openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java (original) +++ openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/StoredProcedureQueryImpl.java Sun Jun 7 18:12:39 2015 @@ -29,12 +29,18 @@ import org.apache.openjpa.util.UserExcep import java.util.Calendar; import java.util.Date; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import javax.persistence.*; +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; import javax.persistence.NoResultException; import javax.persistence.NonUniqueResultException; +import javax.persistence.Parameter; +import javax.persistence.ParameterMode; +import javax.persistence.StoredProcedureQuery; +import javax.persistence.TemporalType; /** * Implements Store Procedure based query for JPA facade. @@ -61,6 +67,7 @@ public class StoredProcedureQueryImpl im private final MultiQueryMetaData _meta; private QueryResultCallback _callback; private boolean _declaredParams; // mainly a flag for now (null or not) + private Iterator<MultiQueryMetaData.Parameter> cursorIterator; /** * Construct a query for executing a Stored Procedure. @@ -133,6 +140,19 @@ public class StoredProcedureQueryImpl im execute(); try { Object list = _callback.callback(); + if (list == null) { // check if there is a cursor + if (cursorIterator == null) { + cursorIterator = _meta.getParameters().iterator(); + } + while (cursorIterator.hasNext()) { + final MultiQueryMetaData.Parameter p = cursorIterator.next(); + if (p.getMode() == MultiQueryMetaData.Parameter.Mode.CURSOR) { + list = p.getName() == null ? + getOutputParameterValue(p.getPosition()) : getOutputParameterValue(p.getName()); + break; + } + } + } RuntimeExceptionTranslator trans = PersistenceExceptions .getRollbackTranslator(_delegate.getEntityManager()); return new DelegatingResultList((ResultList) list, trans); Modified: openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java URL: http://svn.apache.org/viewvc/openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java?rev=1684055&r1=1684054&r2=1684055&view=diff ============================================================================== --- openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java (original) +++ openjpa/branches/openjpa_jpa-2.1/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java Sun Jun 7 18:12:39 2015 @@ -758,6 +758,7 @@ public class XMLPersistenceMetaDataParse return false; } meta.registerParameter(new MultiQueryMetaData.Parameter( + meta.getParameterCount(), attrs.getValue("name"), type, MultiQueryMetaData.Parameter.Mode.valueOf(attrs.getValue("mode")))); return true;