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

    Error writing a blob

    skethire Newbie

      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
          Steven Hawkins Master

          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
            Steven Hawkins Master

            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
              Brian Dudley Newbie

              (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
                Steven Hawkins Master

                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 Newbie

                  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