Announcement Announcement Module
Collapse
No announcement yet.
Retrieving Blob from oracle 9i and converting it to InputStream. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Retrieving Blob from oracle 9i and converting it to InputStream.

    Hi All,
    I'm working with Spring ,Hibernate 3 and oracle 9i DB.

    I'm having a problem while retrieving a Blob from the ORACLE 9i DB and converting it to InputStream.

    The Hibernate definition for the blob is :
    Code:
    ...
    		<property name="content" type="blob">
    			<column name="CONTENT"/>
    		</property>	
    ...
    I have also tried it like that :
    Code:
    		<property name="content">
    		<column name="CONTENT" sql-type="MEDIUMBLOB"/>
    		</property>
    The getter and setter defined as :
    Code:
    public Blob getContent(); public void setContent(Blob content);
    The transformation is being done as follows:

    For the saving part : (which works fine)
    (fileResourceDTO.getContentStream() retrieves InputSteam)
    Code:
    Blob contentStream = null; contentStream = Hibernate.createBlob(fileResourceDTO.getContentStream());
    For the loading part :
    Code:
     
    Blob blob = fileResource.getContent();
    InputStream is = blob.getBinaryStream();
    which generate an error message :
    Code:
    java.io.IOException: must be connected to the server
    	at oracle.jdbc.driver.DatabaseError.SQLToIOException(DatabaseError.java:556)
    	at oracle.jdbc.driver.OracleBlobInputStream.needBytes(OracleBlobInputStream.java:189)
    	at oracle.jdbc.driver.OracleBufferedStream.read(OracleBufferedStream.java:130)
    	at oracle.jdbc.driver.OracleBufferedStream.read(OracleBufferedStream.java:110)
    	at TestSpringHibernate.main(TestSpringHibernate.java:135)

    Please send me any answer or a suggestion you can think of...
    NOTE :
    The same code works just great using Hibernate only...

  • #2
    Here is the solutionn, thanks to a "WONDER" called spring, handling blobs is a piece of cake.

    Make the following change in yourhbm file:-

    Code:
    <property name="content" type="org.springframework.orm.hibernate3.support.BlobByteArrayType">
          <column name="CONTENT"/>
    </property>
    In your bean class set the datatype of "content" to byte[]

    In your spring application-context xml file add the following :-

    1] Create a native JDBC extractor, depending on your Datasource. For e.g the following uses a C3P0 extractor.

    Code:
    <bean id="c3P0NativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.C3P0NativeJdbcExtractor" />
    2] Add the LOBHandler:-

    Code:
    <bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
    		<property name="nativeJdbcExtractor"><ref local="c3P0NativeJdbcExtractor" /></property>	
    	</bean>
    With all the above changes, you should be good to go!

    Comment


    • #3
      Thanks a lot for your time nikhil78.

      But I realy need to stick to the solution using an InputStream. I need to upload large files and using the byteArray solution overload the system and damage performance.

      I just need to understand why the getBinaryStream does'nt do the job correctly.

      when I try reading from the inputString (is.read()) after the getBinaryStream i'm getting the error i have mentioned previously.

      Comment


      • #4
        You don't have to have it as a byte[] ofcourse you can implement yuor own Blob*Type ofcourse.

        The reading fails because after retrieval of the object the connection to the database is closed. Without a database connection no reading the blob...

        Comment


        • #5
          HI,
          we are using open session in view pattern and we strongly want to use streams. we don't see a reason why working directly with hibernate we can get a stream and when we are working with spring we can not.
          Is there a way to leave the connection open?
          Other way to use streams?
          It seems a bad practive to load large files into memory using byte array.
          Do'nt you think the same?

          Comment


          • #6
            Reading from the InputStream in the end will do the same, load it into memory.

            In your Test i don't see an OpenSessionInViewFilter/Interceptor anywhere?. Can you post your full testcode and necessary configuration? I think it is a problem of your Transaction settings/setup.
            Last edited by Marten Deinum; Aug 22nd, 2007, 09:41 AM.

            Comment


            • #7
              Code we use

              see attached file

              Comment


              • #8
                Your test class uses a XmlBeanFactory which quite effectifly renders all your proxies useless. Here the difference is explained.

                For writing testcases it is easier to extend the Spring supplied test classes, saves you from writing a lot of boilerplate code (like your session synchronization etc.).

                The part below needs to be changed.
                Code:
                //Refrence to the resource applicationContext.xml file. main xml for
                // spring initialization.
                Resource res = new ClassPathResource("applicationContext.xml");
                
                //Create factory for the resource.
                BeanFactory factory = new XmlBeanFactory(res);
                to

                Code:
                ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");

                Comment


                • #9
                  Thank you very very !!!

                  Thank you very very much, i will read it and try out your suggestions.
                  Last edited by eitanbaron; Aug 26th, 2007, 04:05 AM.

                  Comment

                  Working...
                  X