camel-mybatis - issues with calling Oracle Stored procedure with multiple resultsets - oracle

I am using camel-mybatis (version 2.12) component in Fuse 6.1 environment to invoke an oracle SP with 2 resultsets. The request is a HashMap and once mybatis maps the resultsets to java beans, the List is again saved in the original HashMap itself.
Here is the snippet of SqlMap:
<select
id="searchUsers"
parameterType="java.util.HashMap"
statementType="CALLABLE">
{call ORACLE.SP_NAME_1(
#{userId,mode=IN,jdbcType=VARCHAR},
#{maxResultsCount,mode=IN,jdbcType=DECIMAL},
#{view,mode=IN,jdbcType=VARCHAR},
#{statusInfo,mode=OUT,jdbcType=CURSOR,resultMap=statusInfoRowMap},
#{memberInfo,mode=OUT,jdbcType=CURSOR,resultMap=claimInfoRowMap})}
And here is how I invoke the mybatis component:
<setBody>
<groovy>
[
userId:'ID-1234',
maxResultsCount:20,
view:'MEMBER',
]
</groovy>
</setBody>
<to uri="mybatis:searchUsers?statementType=SelectOne" />
Since there are no result object (all the results are stored in the original requested HashMap itself), MyBatisProducer is setting null to exchange OUT message. The original body which contains the results from stored procedure is lost.
The Question is: is this the expected behaviour? mybatis component already stores the result in exchange header, so why to update the body as well?
The workaround I had to do was - to store the original body to a header, invoke mybatis and reset body from the header (which has the stored procedure result now) :
<setBody>
<groovy>
[
userId:'ID1234',
maxResultsCount:20,
view:'MEMBER'
]
</groovy>
</setBody>
<setHeader headerName="originalRequest">
<simple>${body}</simple>
</setHeader>
<to uri="mybatis:searchUsers?statementType=SelectOne" />
<setBody>
<simple>${in.headers.originalRequest}</simple>
</setBody>
<log message="status: ${body[statusInfo]}" />
Any help would be appreciated.. Thanks.

Ah well spotted. Log a JIRA ticket so we can improve this and avoid setting the body to null, when you use a stored procedure.
There is a link to the issue tracker here
http://camel.apache.org/support

Related

Mule: Invoking an Oracle stored procedure which returns a table of custom type

I am using Mule CE 3.6.1. I have the following Database connector configuration calling an Oracle stored procedure.
<db:stored-procedure config-ref="Oracle_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[call get_phone_email(:userId, :tPhoneRecord)]]></db:parameterized-query>
<db:in-param name="userId" type="NUMERIC" value="#[payload]" />
<db:out-param name="tPhoneRecord" type="ARRAY" />
</db:stored-procedure>
Parameter tPhoneRecord is defined as IS TABLE OF phone_email%ROWTYPE (i.e. table of records) in the stored procedure. I have tried specifying the parameter type ARRAY but get the error:
Message : Invalid argument(s) in call (java.sql.SQLException). Message payload is of type Object[]
Code : MULE_ERROR--2
I have also tried using other out-param types or not specifying a type without success.
Please let me know what out-param type I should use for an Oracle table of records, or if I should do this in Java instead. Many thanks in advance.
You can use the below solution for out parameter.
<db:oracle-config name="Oracle_Configuration" url="jdbc:oracle:thin:#54.175.245.218:1581:xe" user="user" password="4321" >
</db:oracle-config>
<db:data-type name="INtypename" id="12"/>
<!-- VARCHAR id=12 -->
<db:data-type name="OUTtypename" id="2002"/>
<!-- STRUCT id=2002 -->
</db:data-types>
...
<db:stored-procedure config-ref="Generic_Database_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[CALL storedprocfnc(:INtypename,:OUTtypename);]]></db:parameterized-query>
<db:in-param name="INtypename" value="#[payload]"/>
<db:out-param name="OUTtypename" />
</db:stored-procedure>

WSO2 Filter Proxy Boolean Expression evaluator issue

in my proxy i'm using a filter mediator. My target is to activate a sequence if some conditions on some properties are verified:
codice = 0
idElementoCross is different from null or empty string or if it exists
tipoElementoCross is different from null or empty string or if it exists
i wrote this condition:
<sequence>
<property name="codice" expression="//codice"></property>
<property name="idElementoCross" expression="//idElementoCross"></property>
<property name="tipoElementoCross" expression="//tipoElementoCross"></property>
<filter xpath="boolean(fn:get-property('codice')=0 and fn:get-property('tipoRisposta')='worker' and fn:get-property('tipoElementoCross')!='null' and fn:get-property('idElementoCross')!='null' and fn:get-property('tipoElementoCross')!='' and fn:get-property('idElementoCross')!='' and fn:get-property('tipoElementoCross') and fn:get-property('idElementoCross'))">
<then> ...
but in my log i see that esb enter the sequence even if idElementoCross and tipoElementoCross are empty.
Im using WSO2 ESB 4.8.1.
What am i missing?
This is because when there is no value, //tipoElementoCross return the node and not the text value :
send <tipoElementoCross></tipoElementoCross>
//tipoElementoCross = <tipoElementoCross></tipoElementoCross>
//tipoElementoCross/text() =

Refer spring batch job parameters within internal map

I'm trying to refer to a spring batch job parameter within inner map (that i created).
No luck until now ,
The error message that i get is :
EL1043E:(pos 20): Unexpected token. Expected 'identifier' but was 'lcurly({)'
The expression that I'm trying to evaluate is :
#{fragmentsMap[#{jobParameters['message.source']}]}
The Map is :
<util:map id="fragmentsMap">
<entry key="dfg" value="ABC" /></util:map>
The Item Reader that I'm trying to config is :
<bean id="eventItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader" scope="step"
p:fragmentRootElementName="#{fragmentsMap[#{jobParameters['message.source']}]}"
p:resource="file:/#{jobParameters['message.input']}"
p:unmarshaller-ref= "itemUnmarshaller"/>
I would appreciate any advice.

WSO2 DSS call procedure with CLOB response raise ORA-22835 error

I have a Oracle procedure
TEST_XML_PARM_CALLER
call procedure
TEST_XML_PARM_CALLEE(parm1 IN CLOB, parm2 OUT CLOB)
via WSO2 ESB, WSO2 DSS.
The parm1 is CLOB parameter, send XML content from procedure TEST_XML_PARM_CALLER,
and the parm2 is CLOB parameter that return XML content from procedure TEST_XML_PARM_CALLEE.
The call from TEST_XML_PARM_CALLER to ESB to DSS to TEST_XML_PARAM_CALLEE is correct by CLOB content (string length great than 4000),
but return parameter(parm2) will raise error when length great than 4000, like bellow
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 6024, maximum: 4000)
In WSO2 DSS, the configuration as below
<data name="test_xml_parm">
<config id="test_db">
<property name="carbon_datasource_name">test_db</property>
</config>
<query id="qry_test_xml_parm" useConfig="test_db">
<sql>call TEST_XML_PARM_CALLEE(?,?)</sql>
<result element="rcd" rowName="row">
<element column="rtn_clob" name="rtn_clob" xsdType="string"/>
</result>
<param name="clob_xml" ordinal="1" sqlType="STRING"/>
<param name="rtn_clob" ordinal="2" sqlType="STRING" type="OUT"/>
</query>
<operation name="op_test_xml_parm">
<call-query href="qry_test_xml_parm">
<with-param name="clob_xml" query-param="clob_xml"/>
</call-query>
</operation>
</data>
anyone can tell me how to fix it ?
This is an old question and I don't know about the wso2Dss version.
I had a similar problem with wso2DSS 4.4.2
1)set parameters sqlType to "CLOB"
2) replace ojdbc5.jar with ojdbc6.jar (or you will get java.lang.AbstractMethodError: setClob is abstract error.
I still have problems with xml (I must put input in CDATA and the response is ecaped (< => < ) but I should be able to deal with it on the ESB side.

Hibernate: java.sql.BatchUpdateException: ORA-01732 on immutable view

First, see the Hibernate mapping excerpts: there are mutable ParentObjects in an Oracle DB TABLE referencing immutable ChildObjects in an Oracle DB VIEW:
1) there is a set of ChildObjectInView inside a ParentObject, defined as not mutable, without cascading:
<class name="ParentObject" table="t_parentobject">
...
<set name="childObjectsInView" cascade="none" lazy="true" mutable="false">
<key column="coivId" />
<one-to-many class="com.it.ChildObjectInView"/>
</set>
</class>
2) the ChildObjectInView is defined as
<class name="ChildObjectInView" table="view_coiv" mutable="false" lazy="true">
...
<many-to-one name="parentObject" column="parentObjectId" update="false" insert="false" class="com.it.ParentObject" not-null="true" outer-join="true">
</many-to-one>
</class>
Calling com.it.TestServiceImpl.saveParentObject() results in an Oracle error ORA-01732: data manipulation operation not legal on this view, although mutable="false" attributes in the hibernate mappings are set. Why this error?
com.it.TestBean|could not delete collection: [com.it.ParentObject.childObjectsInView#398500]
org.hibernate.exception.SQLGrammarException: could not delete collection: [com.it.ParentObject.childObjectsInView#398500]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:1071)
at org.hibernate.action.CollectionRemoveAction.execute(CollectionRemoveAction.java:28)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at com.it.TestServiceImpl.saveParentObject(TestServiceImpl.java:418)
Caused by: java.sql.BatchUpdateException: ORA-01732: data manipulation operation not legal on this view
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10296)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:216)
at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:34)
at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:1048)
... 69 more
I finally found out by myself that there were cases in that a ParentObject was newly created with the set ParentObject.childObjectsInView being set to null.
Saving this newly created ParentObject Hibernate tried to run a DELETE FROM <view> WHERE id=<objectid>. This statement is like a reset of all objects inside ParentObject.childObjectsInView.
I think this default behavior of Hibernate is wrong at this place, a bug report should be opened: Hibernate has the information that the child is immutable so any manipulating SQL should be suppressed.
Workaround:
Assure that an empty collection is always set to ParentObject.childObjectsInView (instead of null).

Resources