5 Replies Latest reply on Apr 12, 2013 3:18 PM by skethire

    Error writing a blob

    skethire

      I have a simple view model with a blob column.  I am trying to read from a file and set the blob.  See my code below.

      I am using Teiid 8.1.FInal

       

      public class ReadWriteFileStreamBlob {

      public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement stmt = null;
        try{
         /* Load Driver Class */
         Class.forName("org.teiid.jdbc.TeiidDriver");
         /* Make a Connection */
         conn = DriverManager.getConnection("jdbc:teiid:ISync@mm://localhost:31000","user", "user");
         /* Prepare the CRUD Statement */
         stmt = conn.prepareStatement("Insert Into DocumentStore(FilePath, file) Values( ?, ?)");
         /* Set Parameters as appropriate. */
        
         File blob = new File("C:/Work/test.docx");
         FileInputStream   fis = new FileInputStream(blob);
         stmt.setString(1,"test.docx");
         stmt.setBlob(2, fis);
         /* Execute */
         stmt.executeUpdate();

        }catch( Exception e ){
         e.printStackTrace();
        }finally{
         try {
          conn.close();
         } catch (SQLException e) {
          e.printStackTrace();
         }
        }

      }

      }

       

       

      I get the following exception.

       

       

      Exception in thread "main" java.lang.StackOverflowError

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

      at org.teiid.jdbc.PreparedStatementImpl.setBlob(PreparedStatementImpl.java:610)

       

      What am I doing wrong here?

        • 1. Re: Error writing a blob
          shawkins

          You are not doing anything wrong, that blob setter is not correct.  Can you log an issue for this? 

           

          The workaround is to set your blob as a blob object.  You can use the Teiid default implemenation for that -

           

          final FileInputStream   fis = new FileInputStream(blob);

          stmt.setString(1,"test.docx");

          stmt.setObject(2, new org.teiid.core.types.BlobImpl(new org.teiid.core.types.InputStreamFactory() {

                      @Override

                      public InputStream getInputStream() throws IOException {

                          return inputStream;

                      }

                  }));

          • 2. Re: Error writing a blob
            shawkins

            Srini,

             

            I went ahead and logged/worked this under https://issues.jboss.org/browse/TEIID-2464 so the fix will be in 8.4 Alpha2.

             

            Steve

            • 3. Re: Error writing a blob
              brdudley

              (working with Srini...)

               

              The workaround gets past the issue with setting a blob. However, it seems to expose a casting problem with the connector. I’ve verified that the problem is with the connector by taking the “Exec” out of the Insert Procedure – in other words the procedure does nothing. With that change, the program runs normally (but is of no use).

               

              The exception is complaining that it cannot cast from a Reference to a java.lang.String. Unless you see something or can think of another test, I can post these results to the forum.

               

              org.teiid.jdbc.TeiidSQLException: org.teiid.query.sql.symbol.Reference cannot be cast to java.lang.String

                     at org.teiid.jdbc.TeiidSQLException.create(TeiidSQLException.java:113)

                     at org.teiid.jdbc.TeiidSQLException.create(TeiidSQLException.java:70)

                     at org.teiid.jdbc.StatementImpl.postReceiveResults(StatementImpl.java:656)

                     at org.teiid.jdbc.StatementImpl.access$100(StatementImpl.java:62)

                     at org.teiid.jdbc.StatementImpl$2.onCompletion(StatementImpl.java:512)

                     at org.teiid.client.util.ResultsFuture.done(ResultsFuture.java:130)

                     at org.teiid.client.util.ResultsFuture.access$200(ResultsFuture.java:37)

                     at org.teiid.client.util.ResultsFuture$1.receiveResults(ResultsFuture.java:75)

                     at org.teiid.net.socket.SocketServerInstanceImpl.receivedMessage(SocketServerInstanceImpl.java:222)

                     at org.teiid.net.socket.SocketServerInstanceImpl.read(SocketServerInstanceImpl.java:257)

                     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

                     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

                     at java.lang.reflect.Method.invoke(Unknown Source)

                     at org.teiid.net.socket.SocketServerConnectionFactory$ShutdownHandler.invoke(SocketServerConnectionFactory.java:102)

                     at $Proxy1.read(Unknown Source)

                     at org.teiid.net.socket.SocketServerInstanceImpl$RemoteInvocationHandler$1.get(SocketServerInstanceImpl.java:356)

                     at org.teiid.jdbc.StatementImpl.executeSql(StatementImpl.java:521)

                     at org.teiid.jdbc.PreparedStatementImpl.executeUpdate(PreparedStatementImpl.java:217)

                     at cg.test.filestream.ReadWriteFileStreamBlob.main(ReadWriteFileStreamBlob.java:60)

              Caused by: org.teiid.core.TeiidException: org.teiid.query.sql.symbol.Reference cannot be cast to java.lang.String

                     at org.teiid.client.ResultsMessage.setException(ResultsMessage.java:172)

                     at org.teiid.dqp.internal.process.RequestWorkItem.sendError(RequestWorkItem.java:787)

                     at org.teiid.dqp.internal.process.RequestWorkItem.close(RequestWorkItem.java:483)

                     at org.teiid.dqp.internal.process.RequestWorkItem.process(RequestWorkItem.java:318)

                     at org.teiid.dqp.internal.process.AbstractWorkItem.run(AbstractWorkItem.java:49)

                     at org.teiid.dqp.internal.process.RequestWorkItem.run(RequestWorkItem.java:219)

                     at org.teiid.dqp.internal.process.DQPWorkContext.runInContext(DQPWorkContext.java:249)

                     at org.teiid.dqp.internal.process.ThreadReuseExecutor$RunnableWrapper.run(ThreadReuseExecutor.java:123)

                     at org.teiid.dqp.internal.process.ThreadReuseExecutor$3.run(ThreadReuseExecutor.java:298)

                     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

                     at java.lang.Thread.run(Thread.java:662)

              Caused by: java.lang.ClassCastException: org.teiid.query.sql.symbol.Reference cannot be cast to java.lang.String

                     at org.teiid.translator.file.FileExecutionFactory$1.execute(FileExecutionFactory.java:181)

                     at org.teiid.dqp.internal.datamgr.ConnectorWorkItem.execute(ConnectorWorkItem.java:261)

                     at org.teiid.dqp.internal.process.DataTierTupleSource.getResults(DataTierTupleSource.java:425)

                     at org.teiid.dqp.internal.process.DataTierTupleSource.nextTuple(DataTierTupleSource.java:270)

                     at org.teiid.query.processor.relational.AccessNode.nextBatchDirect(AccessNode.java:279)

                     at org.teiid.query.processor.relational.RelationalNode.nextBatch(RelationalNode.java:279)

                     at org.teiid.query.processor.relational.ProjectNode.nextBatchDirect(ProjectNode.java:146)

                     at org.teiid.query.processor.relational.RelationalNode.nextBatch(RelationalNode.java:279)

                     at org.teiid.query.processor.relational.RelationalPlan.nextBatch(RelationalPlan.java:148)

                     at org.teiid.query.processor.QueryProcessor.nextBatchDirect(QueryProcessor.java:143)

                     at org.teiid.query.processor.QueryProcessor.nextBatch(QueryProcessor.java:109)

                     at org.teiid.query.processor.BatchIterator.finalRow(BatchIterator.java:70)

                     at org.teiid.common.buffer.AbstractTupleSource.getCurrentTuple(AbstractTupleSource.java:69)

                     at org.teiid.query.processor.BatchIterator.getCurrentTuple(BatchIterator.java:82)

                     at org.teiid.common.buffer.AbstractTupleSource.hasNext(AbstractTupleSource.java:91)

                     at org.teiid.query.processor.proc.ProcedurePlan.executePlan(ProcedurePlan.java:510)

                     at org.teiid.query.processor.proc.CreateCursorResultSetInstruction.process(CreateCursorResultSetInstruction.java:69)

                     at org.teiid.query.processor.proc.ProcedurePlan.processProcedure(ProcedurePlan.java:365)

                     at org.teiid.query.processor.proc.ProcedurePlan.nextBatchDirect(ProcedurePlan.java:293)

                     at org.teiid.query.processor.proc.ProcedurePlan.nextBatch(ProcedurePlan.java:266)

                     at org.teiid.query.processor.QueryProcessor.nextBatchDirect(QueryProcessor.java:143)

                     at org.teiid.query.processor.QueryProcessor.nextBatch(QueryProcessor.java:109)

                     at org.teiid.query.processor.proc.ForEachRowPlan.nextBatch(ForEachRowPlan.java:119)

                     at org.teiid.query.processor.relational.PlanExecutionNode.nextBatchDirect(PlanExecutionNode.java:118)

                     at org.teiid.query.processor.relational.RelationalNode.nextBatch(RelationalNode.java:279)

                     at org.teiid.query.processor.relational.ProjectNode.nextBatchDirect(ProjectNode.java:146)

                     at org.teiid.query.processor.relational.RelationalNode.nextBatch(RelationalNode.java:279)

                     at org.teiid.query.processor.relational.RelationalPlan.nextBatch(RelationalPlan.java:148)

                     at org.teiid.query.processor.QueryProcessor.nextBatchDirect(QueryProcessor.java:143)

                     at org.teiid.query.processor.QueryProcessor.nextBatch(QueryProcessor.java:109)

                     at org.teiid.query.processor.BatchCollector.collectTuples(BatchCollector.java:153)

                     at org.teiid.dqp.internal.process.RequestWorkItem.processMore(RequestWorkItem.java:382)

                     at org.teiid.dqp.internal.process.RequestWorkItem.process(RequestWorkItem.java:291)

                     ... 8 more

               

              • 4. Re: Error writing a blob
                shawkins

                Presumably you have a scenario like:

                 

                create foreign procedure p (a string);

                create view vw options (updatable true) as

                  select 'a' as a;

                create trigger on vw instead of insert as

                  for each row begin atomic

                    exec p("new".a);

                  end

                 

                Where you are passing the path name via new parameter that was set on the user query as a bind value:

                 

                insert into vw (a) values (?)

                 

                When I run this on 8.3/8.4 (latest), I see the proper string value being passed to the procedure execution.  Can you retest on 8.3 to see if this has been addressed? 

                • 5. Re: Error writing a blob
                  skethire

                  The same workflow (with the code changed as below) worked with Teiid 8.3.Final.

                  I did not change the vdb attached to this thread.

                   

                  public static void main(String[] args) {

                      Connection conn = null;

                      PreparedStatement stmt = null;

                      try{

                          /* Load Driver Class */

                          Class.forName("org.teiid.jdbc.TeiidDriver");

                   

                          /* Make a Connection */

                          conn = DriverManager.getConnection("jdbc:teiid:IBitSync@mm://localhost:31000","user", "user");

                   

                          /* Prepare the CRUD Statement */

                          stmt = conn.prepareStatement("Insert Into DocumentStore(FilePath, file) Values( ?, ?)");

                   

                   

                          /* Set Parameters as appropriate. */

                   

                          File blob = new File("C:/Temp/Data.docx");

                          final FileInputStream   fis = new FileInputStream(blob);

                          stmt.setString(1,"Data.docx");

                          stmt.setObject(2, new org.teiid.core.types.BlobImpl(new org.teiid.core.types.InputStreamFactory() {

                                 @Override

                                 public InputStream getInputStream() throws IOException {

                                     return fis;

                                 }

                                 }));

                   

                   

                           /* Execute */

                           stmt.executeUpdate();

                   

                   

                           }catch( Exception e ){

                               e.printStackTrace();

                           }finally{

                               try {

                                    conn.close();

                               } catch (SQLException e) {

                                    // TODO Auto-generated catch block

                                    e.printStackTrace();

                               }

                           }

                   

                  }

                  1 of 1 people found this helpful