[ 
https://issues.apache.org/jira/browse/DERBY-6923?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15884306#comment-15884306
 ] 

Bryan Pendleton commented on DERBY-6923:
----------------------------------------

Hi! Thanks for the clean and simple test programs.

Looking at your programs in detail, it seems like the crucial difference you're 
exploring is between:
{code}
    insertStatement.setClob(2, new 
InputStreamReader(select.getClob(2).getAsciiStream()));
    insertStatement.setBlob(3, select.getBlob(3).getBinaryStream());
{code}
versus 
{code}
    insertStatement.setClob(2, select.getClob(2));
    insertStatement.setBlob(3, select.getBlob(3));
{code}

The Derby BLOB and CLOB implementation is a bit murky to me, I'm afraid, but I 
believe that you are running into the behavior that the Derby documentation 
describes here: http://db.apache.org/derby/docs/10.13/ref/rrefjdbc96386.html
{quote}
The Derby implementation of the java.sql.Blob and java.sql.Clob interfaces is 
LOCATOR-based, meaning that the implementation provides a logical pointer to a 
LOB rather than a complete copy of the object. Also, Derby does not materialize 
a LOB when you use the BLOB or CLOB data type. You can, however, call methods 
on a java.sql.Blob and java.sql.Clob object to materialize it (that is, to 
retrieve the entire object or parts of it).

...

Use the getBlob and getClob methods of the java.sql.ResultSet interface to 
retrieve a LOB using its locator. You can then materialize all or part of the 
LOB by calling Blob and Clob methods. Alternatively, you can call the 
ResultSet.getBytes method to materialize a BLOB, and you can call the 
ResultSet.getString method to materialize a CLOB.
{quote}

In other words, I suspect that in your second block of code, you are executing 
an INSERT statement in which the blob and clob values that you have provided as 
parameters are "non-materialized".

But in the first block of code, you are executing an INSERT statement in which 
the blob and clob values are "materialized", which occurred when you called 
getBinaryStream and getAsciiStream

The behavior of locator-based large objects in Derby has historically been 
quite a bit more complicated in client-server configurations than in embedded 
configurations, which is I suspect why you are seeing the behavior only in the 
client-server configuration.

In the client-server configuration, the blob/clob values have to be fully 
copied from the server to the client in order to be "materialized", and then 
have to be fully copied **back** from the client to the server when being 
inserted into the other table.

So, I suspect what's going wrong is that the Derby JDBC client software is 
supposed to detect when you have performed a setBlob() or setClob() with a 
non-materialized blob or clob as the source object, and then should materialize 
that blob when you execute the insert statement.

However, it seems like the Derby JDBC client is not doing that properly, with 
the result that, in your case, things work fine if your program is careful to 
materialize the blob itself, rather than depending on the Derby JDBC client to 
do that.

That is, I feel like the behavior you are demonstrating is a bug, but I'm (a) 
not sure how to fix it, and (b) trying to suggest that, in the short term, you 
may need to continue to use the explicit materialization workaround you've 
found in order to get the desired behavior in your program.

> Passing a ClientClob or ClientBlob from another connection to an INSERT 
> statement results in 'null' being written.
> ------------------------------------------------------------------------------------------------------------------
>
>                 Key: DERBY-6923
>                 URL: https://issues.apache.org/jira/browse/DERBY-6923
>             Project: Derby
>          Issue Type: Bug
>          Components: Network Client, Network Server
>    Affects Versions: 10.13.1.1
>         Environment: Java 8
> MacOS
> Windows
>            Reporter: Gordon Innes
>            Priority: Critical
>         Attachments: DerbyEmbeddedOnly.java, DerbyNetworkOnly.java, 
> DerbyNetworkRead.java, DerbyNetworkWrite.java
>
>
> When assigning a Blob or Clob from a ResultSet to a PreparedStatement 
> parameter on a second connection, null is written to the column instead.
> Attached the same example using Embedded->Embedded, Embedded->Network, 
> Network->Embedded and Network->Network.
> Only the Network->Network example exhibits the fault.
> Originally discovered in HA-JDBC's sync code with 2 derby instances on 
> Windows. Example were tested using MacOS. Both were running on Oracle Java 8 
> VMs.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to