[ https://issues.apache.org/jira/browse/IBATIS-397?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12474626 ]
Jan Vissers commented on IBATIS-397: ------------------------------------ Although the typehandler for plain SELECT statements could be simplified using 'OBJECT' instead of the more intensive coding around 'Oracle' specific - the problem with CallableStatements remain. So indeed a 'fix' would be helpful. I'm testing with the following settings: -- Oracle function CREATE OR REPLACE FUNCTION GET_XML(P_I IN VARCHAR2) RETURN XMLTYPE IS BEGIN RETURN XMLTYPE('<'||P_I||'>Hello World!</'||P_I||'>'); END; / <!-- Mapping segment --> <typeAlias alias="XMLTypeHdl" type="com.cumquatit.examples.ibatis.xmltype.XMLTypeHandlerCallback" /> <procedure id="xmltype" parameterClass="map">{ #doc,jdbcType=OBJECT,handler=XMLTypeHdl,mode=OUT# = call get_xml(#name,jdbcType=VARCHAR,mode=IN#) } </procedure> Runnin the tester results in: Exception in thread "main" com.ibatis.common.jdbc.exception.NestedSQLException: --- The error occurred in com/cumquatit/examples/ibatis/xmltype/XmltypeData.xml. --- The error occurred while executing query procedure. --- Check the { ? = call get_xml(?) }. --- Check the output parameters (register output parameters failed). --- Cause: java.sql.SQLException: Invalid column type at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:185) at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104) at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:566) at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:541) at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:106) at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:83) at com.cumquatit.examples.ibatis.xmltype.XMLTypeDataTester.main(XMLTypeDataTester.java:37) Caused by: java.sql.SQLException: Invalid column type at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208) at oracle.jdbc.driver.OracleStatement.getInternalType(OracleStatement.java:3432) at oracle.jdbc.driver.OracleCallableStatement.registerOutParameterInternal(OracleCallableStatement.java:125) at oracle.jdbc.driver.OracleCallableStatement.registerOutParameter(OracleCallableStatement.java:268) at oracle.jdbc.driver.OracleCallableStatement.registerOutParameter(OracleCallableStatement.java:348) at com.ibatis.sqlmap.engine.execution.SqlExecutor.registerOutputParameters(SqlExecutor.java:428) at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQueryProcedure(SqlExecutor.java:275) at com.ibatis.sqlmap.engine.mapping.statement.ProcedureStatement.sqlExecuteQuery(ProcedureStatement.java:34) at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173) ... 6 more > Support for Oracle "OPAQUE" > --------------------------- > > Key: IBATIS-397 > URL: https://issues.apache.org/jira/browse/IBATIS-397 > Project: iBatis for Java > Issue Type: Improvement > Components: SQL Maps > Affects Versions: 2.2.0, 2.3.0 > Reporter: Jan Vissers > > Based on the custom type handler described in: > http://opensource.atlassian.com/confluence/oss/display/IBATIS/XMLTypeHandlerCallback.java > we tried to use this handler not only for "regular select" statements but > also for "callable statements". As it turns out the current iBatis codebase > doesn't allow us to use and/or extend the type handler to fully support > Oracle's RDBMS XMLType datatype. > I've experimented a bit and suggest the following solution: > 1) Modify the JdbcTypeRegistry class in order for it to contain the > ORACLEOPAQUE (much like the ORACLECURSOR already specified) > setType("ORACLEOPAQUE", 2007); > 2) Modify the CallableStatementResultSet class to have it expose its > decorated "CallableStatement" instance: > public CallableStatement getCs() { > return cs; > } > With these two modifications we can declare the mapping as follows: > <parameter property="doc" jdbcType="ORACLEOPAQUE" mode="OUT" > typeHandler="XMLTypeHandlerCallback" typeName="SYS.XMLTYPE"/> > We have to change the XMLTypeHandlerCallback (referenced at the top) in order > for the getResult() to determine whether to perform work for a > CallableStatementResultSet or an OracleResultSet, like so: > //The handler getResult > public Object getResult(ResultGetter getter) throws SQLException { > if (getter.getResultSet() instanceof CallableStatementResultSet) { > if (((CallableStatementResultSet) getter.getResultSet()).getCs() > instanceof OracleCallableStatement) { > OracleCallableStatement ocsmt = (OracleCallableStatement) > ((CallableStatementResultSet) getter.getResultSet()).getCs(); > // go to work > } else { > throw new UnsupportedOperationException("XMLType mapping only > supported for Oracle RDBMS"); > } > } else > if (getter.getResultSet() instanceof OracleResultSet) { > // go to work > } else { > throw new UnsupportedOperationException("XMLType mapping only > supported for Oracle RDBMS"); > } > } -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.