On Jan 18, 2011, at 8:28 PM, David Balažic wrote:

> So, does that testcase really work on Oracle?

Yes. Now revisiting the tests, we are cheating to make the generic mapping work 
with Oracle. The reason for this is Oracle driver's insistence on circumventing 
basic JDBC abstractions. We take a generic mapping [1] and alter the procedure 
object in the test code [2]. Notice how we install Oracle-specific type as an 
OUT parameter type:

// the type used below is "oracle.jdbc.OracleTypes.CURSOR"
proc.addCallParameter(new ProcedureParameter("result", 
OracleAdapter.getOracleCursorType(), ProcedureParameter.OUT_PARAMETER));

For now the above (creating or tweaking procedure mapping metadata in the code) 
is one possible way for dealing with Oracle. Going forward, we may either 
support numeric values for column types (so that a user could map this column 
as "-10", same as "oracle.jdbc.driver.OracleTypes.CURSOR"). Or maybe we should 
dynamically rewrite Cayenne-mapped stored procedures, adding CURSOR parameter 
inside Cayenne (not yet sure how what part of the mapping should trigger such 
behavior).\

And unfortunately there's little hope that after all these years Oracle will 
finally fix their driver (or at least implement ParameterMetaData JDBC 
interface so that Oracle-specific types could be used dynamically).

Andrus


[1] 

<procedure name="cayenne_tst_select_proc">
  <procedure-parameter name="aName" type="VARCHAR" length="254" direction="in"/>
  <procedure-parameter name="paintingPrice" type="INTEGER" direction="in"/>
</procedure>


[2]  OracleStackAdapter.java:

public void tweakProcedure(Procedure proc) {
       if 
(DataContextProcedureQueryTest.SELECT_STORED_PROCEDURE.equals(proc.getName())
               && proc.getCallParameters().size() == 2) {
           List params = new ArrayList(proc.getCallParameters());

           proc.clearCallParameters();
           proc.addCallParameter(new ProcedureParameter("result", OracleAdapter
                   .getOracleCursorType(), ProcedureParameter.OUT_PARAMETER));
           Iterator it = params.iterator();
           while (it.hasNext()) {
               ProcedureParameter param = (ProcedureParameter) it.next();
               proc.addCallParameter(param);
           }

           proc.setReturningValue(true);
       }
   } 

Reply via email to