[ http://issues.apache.org/jira/browse/IBATIS-283?page=comments#action_12416083 ]
Jeff Butler commented on IBATIS-283: ------------------------------------ This does not look like a bug report to me - rather it is a request for help. Please use the mailing list for help. IBATIS-145 and IBATIS-242 both deal with this issue and provide examples. Both are apparantly fixed in SVN. Until the next release, you may need to build iBATIS from source to make a TypeHandler work as you need it to. I'll close this as "invalid" unless you can provide more information that indicates a new bug in iBATIS. > Oracle Objects support in iBatis using TypeHandler > -------------------------------------------------- > > Key: IBATIS-283 > URL: http://issues.apache.org/jira/browse/IBATIS-283 > Project: iBatis for Java > Type: Improvement > Components: SQL Maps > Environment: JBoss, Oracle 9i > Reporter: Ashwin > Priority: Blocker > > We have our legacy database in oracle and the front end of the application > was Oracle forms. Now we wish to change the front end to J2EE. We are using > Spring as service layer that will call iBatis for data exchange. > Now, this legacy database has lots of stored procedures in which some of them > returning oracle objects. We tried getting Oracle objects but I guess they > are not supported by iBatis. We tried using TypeHandlerCallback using example > from following URL: http://issues.apache.org/jira/browse/IBATIS-145 . We are > new to iBatis so please help us with an example or a method to get oracle > objects. > Sending you the code snip lets. > Main.java > SqlMapClient sqlMap; > resource = "SqlMapConfig.xml"; > reader = Resources.getResourceAsReader(resource); > sqlMap = > SqlMapClientBuilder.buildSqlMapClient(reader); > Map map = new HashMap(); > map.put("msnId","555"); > sqlMap.queryForObject("storedFunc", map); > List firstList = (List)map.get("output1"); > Iterator itr = firstList.iterator(); > while(itr.hasNext()) { > VehicleModel vm = > (VehicleModel)itr.next(); > } > > SqlMapConfig.xml > <sqlMapConfig> > <settings cacheModelsEnabled="true" > enhancementEnabled="true" > lazyLoadingEnabled="true" maxRequests="32" > maxSessions="10" maxTransactions="5" > useStatementNamespaces="false" /> > <typeAlias alias="vehicle2Typehandler" type="Vehicle2Typehandler" /> > <typeHandler javaType="VehicleModel" callback="vehicle2Typehandler" /> > <transactionManager type="JDBC" > > <dataSource type="SIMPLE"> > <property name="JDBC.Driver" value="oracle.jdbc.OracleDriver"/> > <property name="JDBC.ConnectionURL" > value="jdbc:oracle:thin:@10.0.4.20:1521:rajeshm"/> > <property name="JDBC.Username" value="system"/> > <property name="JDBC.Password" value="manager"/> > </dataSource> > </transactionManager> > <sqlMap resource="SQLMap.xml" /> > </sqlMapConfig> > SQLMap.xml > <!-- Calling the Function --> > <parameterMap id="funcInput" class="map" > > <parameter property="output1" jdbcType="VEHICLE2" typeName="VEHICLE2" > typeHandler="Vehicle2Typehandler" mode="OUT"/> > <parameter property="msnId" jdbcType="VARCHAR2" > javaType="java.lang.String" mode="IN"/> > </parameterMap> > <procedure id="storedFunc" parameterMap="funcInput"> > {? = call FUNC(?)} > </procedure> > > Vehicle2Typehandler.java > import java.sql.Connection; > import java.sql.SQLException; > import java.sql.Types; > import oracle.sql.ARRAY; > import oracle.sql.ArrayDescriptor; > import oracle.sql.StructDescriptor; > import oracle.sql.STRUCT; > import com.ibatis.sqlmap.client.extensions.ParameterSetter; > import com.ibatis.sqlmap.client.extensions.ResultGetter; > import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback; > import com.ibatis.sqlmap.engine.type.JdbcTypeRegistry; > public class Vehicle2Typehandler implements TypeHandlerCallback > { > static{ > JdbcTypeRegistry.setType("VEHICLE2", Types.STRUCT); > }; > > public void setParameter(ParameterSetter setter, > Object parameter) > throws SQLException { > VehicleModel vehicleModel[] = > (VehicleModel[])parameter; > setter.getPreparedStatement().getConnection(); > Connection conn = > setter.getPreparedStatement().getConnection(); > StructDescriptor structDescriptor = > StructDescriptor.createDescriptor("VEHICLE2", conn); > STRUCT valStruct; > try { > valStruct = new STRUCT(structDescriptor, > conn, vehicleModel); > } catch (SQLException e) { > throw e; > } > setter.setObject(valStruct); > } > public Object getResult(ResultGetter getter) throws > SQLException { > //Array arr = getter.getArray(); > VehicleModel vm[] = > (VehicleModel[])getter.getObject(); > if(vm==null) > return null; > else > //return (String[])arr.getArray(); > return vm; > } > public Object valueOf(String arg0) { > String[] r = new String[1]; > r[0] = arg0; > return r; > } > } > If you notice I have modified the Vehicle2Typehandler.java class from > handling ARRAY type to STRUCT type. > Not sure weather it's the right approach. Getting the following error. > > Exception in thread "main" > com.ibatis.common.jdbc.exception.NestedSQLException: > --- The error occurred in SQLMap.xml. > --- The error occurred while applying a parameter map. > --- Check the funcInput. > --- Check the output parameters (retrieval of output parameters failed). > --- Cause: java.lang.ClassCastException: oracle.sql.STRUCT > Caused by: java.lang.ClassCastException: oracle.sql.STRUCT > at > com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:188) > at > com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104) > at > com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561) > at > com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536) > at > com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93) > at > com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:70) > at Main.main(Main.java:31) > Caused by: java.lang.ClassCastException: oracle.sql.STRUCT > at Vehicle2Typehandler.getResult(Vehicle2Typehandler.java:66) > at > com.ibatis.sqlmap.engine.type.CustomTypeHandler.getResult(CustomTypeHandler.java:64) > at > com.ibatis.sqlmap.engine.execution.SqlExecutor.retrieveOutputParameters(SqlExecutor.java:357) > at > com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQueryProcedure(SqlExecutor.java:305) > 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 > > Caused by: > java.lang.ClassCastException: oracle.sql.STRUCT > at Vehicle2Typehandler.getResult(Vehicle2Typehandler.java:66) > at > com.ibatis.sqlmap.engine.type.CustomTypeHandler.getResult(CustomTypeHandler.java:64) > at > com.ibatis.sqlmap.engine.execution.SqlExecutor.retrieveOutputParameters(SqlExecutor.java:357) > at > com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQueryProcedure(SqlExecutor.java:305) > at > com.ibatis.sqlmap.engine.mapping.statement.ProcedureStatement.sqlExecuteQuery(ProcedureStatement.java:34) > at > com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173) > at > com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104) > at > com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561) > at > com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536) > at > com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93) > at > com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:70) > at Main.main(Main.java:31) > Any Help is appreciated !!!!!!!!!!!!! -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira