Friday, September 17, 2010

Pass Collection to Stored Procedure using iBatis

Today I had a really crazy idea: "Why not making my query work with a list of parameters like I do with Hibernate using the operator IN???"
It sounds simple, Isn't it??? Ok, then try to do it with an Stored Procedure in Oracle :P
Then, this is my Stored Proc (I had to create a Type to have support for Arrays in Oracle, because an Array is not a simple-provided data type): As you can see, my dear visitor, I'm expecting some simple parameters and I'm returning a ResultSet, really straight forward, but the problem comes with the Array of NUMBER (that's why I created my
TYPE NUMBER_ARRAY AS TABLE OF NUMBER
)

The solution to this problem is easier than it seems, just create a Handler dude!!! The magic begins when I transform the Connection (because I have to work at the connection level) provided by the Application Server (WebSphere on this case - If this happens to me on another App Server or with another Connection Pool, I'm going to be in trouble, because the issue will be how to retrieve a Native java.sql.Connection, but that will be another story).
Let's analyze this monster:
* Get Native Connection
*Create my ArrayDescriptor for my Type (these NUMBER_ARRAY is my TYPE I created previously)
*Create my parameter, an ARRAY (al fin y al cabo) and we're set!

Finally this is my mapping file for my stored procedure

And my code lived happily ever after!!! Abur!!!

6 comments:

  1. Thanks for this post!

    But I got an error while using this code
    No enum const class org.apache.ibatis.type.JdbcType.NUMBER_ARRAY in the xml file

    ReplyDelete
  2. Hi Sunil

    NUMBER_ARRAY is a type I created on Oracle not a constant, that's why you see it as "NUMBER_ARRAY"

    ReplyDelete
  3. Hello,
    I followed the exact same procedure to insert blob array in my database
    But i get Cause: java.lang.ClassCastException: oracle.jdbc.driver.T4CConnection incompatible with com.ibm.ws.rsadapter.jdbc.WSJdbcConnection.

    Please help!!..
    Thanks in advance,
    sam

    ReplyDelete
    Replies
    1. Sam

      Are you using WebSphere??

      If this is the line which is giving you problems:
      Connection nativeConnection = (Connection) WSJdbcUtil.getNativeConnection((WSJdbcConnection) stmt.getConnection());

      Just avoid the casting I did by using WSJdbcUtil.getNativeConnection

      Delete
  4. Hi Juca !
    I have around 1 Lakh records in a file . I Am reading those datas from the file (using java code) and storing those datas into a Java Bean. Then I am inserting those JAVA Beans into database using iBatis one by one. It's taking around one hour to insert 1 Lakh records one by one ; And creating a performance issue. I went through the above contents ; but I could not trace-out.

    Is there any solution where I can insert an ARRAYLIST using iBatis ? ?
    Like I can read the entire file and I can store those records into an ARRAYLIST ; Then I will insert the entire bulk data (stored in ARRAYLIST) into database at one go.

    Thanks in Advance . Please Help !!
    Thanks and Regards
    SOMANATH NANDA

    ReplyDelete
  5. Hi,

    I am using Spring Ibatis integration in my project and my doubt is, if we create plain jdbc connection , do we explicitly need to close the connection or will it be taken care by spring

    Thanks,
    Sujendra

    ReplyDelete