Announcement Announcement Module
Collapse
No announcement yet.
Something I found in the OracleLobHandler class Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Something I found in the OracleLobHandler class

    We know this class is responsible for handling BLOB/CLOB types of the Oracle DBMS, but recently I found I cannot use it to handle when CLOB is mapped to java.lang.String with the help of org.springframework.orm.hibernate.support.ClobStri ngType.
    I'm using Oracle 9i, Spring 1.2.6, Hibernate 2 and Tomcat 5.5.12 as the application server. Here are some configuration snippets:
    The SessionFactory:
    <bean id="sessionFactory"
    class="org.springframework.orm.hibernate.LocalSess ionFactoryBean">
    <lobHandler><ref local="oracleLobHandler"/></lobHandler>
    ...
    </bean>
    The lobHandler:
    <bean id="oracleLobHandler"
    class="org.springframework.jdbc.support.lob.Oracle LobHandler"
    lazy-init="true">
    <property name="nativeJdbcExtractor">
    <ref local="nativeJdbcExtractor" />
    </property>
    </bean>
    <bean id="nativeJdbcExtractor"
    class="org.springframework.jdbc.support.nativejdbc .SimpleNativeJdbcExtractor"
    lazy-init="true"/>

    The configuration above I think is very common and I suppose to be right. But when I call my DAO objects to save the object which has a property of the type String and mapped to CLOB, the code fails. The exception is:
    IOException: no more data to Read from socket at
    Oracle.JDBC.dbaccess.DBError.SQLToIOException(DBEr ror.java:716) at
    Oracle.JDBC.driver.OracleClobWriter.flushBuffer(Or acleClobWriter.java:270) at
    Oracle.JDBC.driver.OracleClobWriter.close(OracleCl obWriter.java:232)
    at org.springframework.util.FileCopyUtils.copy(FileCo pyUtils.java:234)
    ......
    I found many people have encountered this exception but I found no solution(or I'm too dull to google them...). I had to debug the code around but found nothing special, Spring was doing what seemed to be alright. Finally I decided to copy the way Spring acts, that is, create a temporary CLOB object through CLOB.createTemporary() and pass it with the same parameters spring provides, and then get a Writer object by calling the getCharacterOutputStream() method of the created CLOB object, then write my String data through this writer. The question I found was that when I was just using Writer.write() to send String data to the CLOB object everything was alright except when I tried to call Writer.close()! When I tried to call Writer.close() on the created writer, the same exception occured, and calling Writer.close() is what FileUtils.copy(String, Writer) will do at its finally block. It seems I had found the way: not to close the writer, but I'm really afraid of the leak of resources. So, could any one please tell me, whether neglecting to close this writer is alright? What's more, I made a test:

    CLOB c = CLOB.createTemporary(conn, true, CLOB.DURATION_SESSION);
    c.open(CLOB.MODE_READWRITE);
    Writer w = c.getCharacterOutputStream();
    WeakReference wr = new WeakReference(w);
    w.write("blahblahblahblahblah...");
    ps.setClob(1, c); // ps is a PreparedStatement object.
    ...
    ps.execute();
    // If I call w.close() at any place below, the same exception will occur but the data has been stored in the database.:S
    conn.commit();
    ps.close();
    conn.close();
    while(wr != null && wr.get() != null) {
    System.out.print(new java.util.Date());
    System.out.print("\t");
    System.out.println("The writer is not cleaned");
    Thread.sleep(10000);
    // System.gc();
    }
    System.out.print("The writer is cleaned!");

    You can see System.gc() is commented out. At first I called System.gc() and the loop ended, wr.get() returned null, that is, the writer is finalized. But if I comment System.gc() out, the loop never ends. So I'm confused: who is responsible to do the clean-up job? The JDBC driver itself or JVM? Will resource leak occur if I don't close the Writer object?
    Sorry for so many words above to describe my problem. I really appreciate your reading and thinking. Thank all, and hail to the one who will kick this puzzle away from me

  • #2
    1. I have not meet this problem before.
    I am using org.springframework.jdbc.support.lob.LobHandler with jdbctemplate directly to handle oracle clob, and it works fine

    2. Maybe u can try another jdbc driver. I meet some problem caused by oracle jdbc driver, and solve it by upgraded it from 9.2.0.6 to 10.2.0.1, and I am using oracle server 9.2.0.6. Oracle said that "the JDBC Thin drivers in Oracle Database 10g are certified to work with the 9.2.x, 9.0.1.x, and 8.1.7 Oracle Database releases." So I suggest u to have a try.


    btw: I am in Beijing

    Comment


    • #3
      I'll try to upgrade my JDBC driver then, for in recent tests I found classes in the current driver behaves rather strangely.
      The ImageDB example that comes with spring distribution uses JdbcTemplate and OracleLobHandler to solve LOB data storing and retrieving, but some developers say this example cannot work with Oracle, and indeed the default configuration ImageDB uses suggests to work with MySQL and its BLOB data type. Yet I have no time to deploy ImageDB and test it...

      Comment


      • #4
        Try 10.2.0.1 driver

        According to the FAQ:
        http://www.oracle.com/technology/tec...aq_0.htm#06_10

        the standard JDBC LOB API methods are now supported. I simply switched to using DefaultLobHandler, and it seems to work fine.

        Comment

        Working...
        X