Subject Re: [Firebird-Java] Re: Invalid Blob ID when inserting blob?
Author Roman Rokytskyy
> We have a Vector which contains elements of 'StringPair' (a class
> which is simply a pair or Strings). In this case the Vector includes
> one StringPair. My code:
> PreparedStatement ps = MyConnection.prepareStatement("UPDATE CAMPUS
> SET VS_OMITTED_DEFS = ? WHERE CAMPUS_SN = 1");
> ps.setObject(1, MyVector);
>
> This fails with the error
> "org.firebirdsql.jdbc.field.TypeConvertionException: Error converting
> to object".
> If I read the JDK correctly, setObject may only be used with a
> java.sql.Type object? Can you confirm that?

You can pass any of the java.lang.* types that has corresponding
getter/setter and java.sql.Date, java.sql.Time and java.sql.Timestamp,
java.sql.Blob, java.sql.Clob, java.sql.Struct, java.sql.Array object.

Specification allows also passing of the java.sql.SQLData which allows
object to save itself into the stream, but this is not supported by JayBird.

> So I had then written my own method which serialises the Vector to a
> byte[] then calls ps.setBytes(1, byte[]).

This is the only correct way to solve your task. JayBird cannot do this for
you, since classes from JayBird and in your Vector can belong to different
classloaders, but there is no method where you can pass classloader that
will be used for serialization/deserialization.

> Because this is the only column in the prepared statement, the method
> also called ps.execute(). But I'd forgotten this, and the caller was
> calling ps.execute() also! I've taken out the second ps.execute() and now
> there is no error.

Ok.

> I had read that the blob is really only a pointer to the actual binary
> object being stored; so I guess that explains the message referring to
> a 'Blob ID'.

Yes, that's exactly what it means.

> I never intend to call execute() twice on the same prepared statement
> (without clearing parameter(s) if re-using); but in this case - although
> it's accidental - I'm wondering (only out of curiousity) what's going on
> internally here? Can someone explain the mechanism?

When you save a blob, a blob with a temporary ID is created and opened for
write (you cannot read from it, it is like OutputStream). This temporary ID
is used in the INSERT statement. Then, when statement is executed (or on
commit, I do not remember exactly), temporary ID is converted into permanent
one. When you tried to use this temporary ID for the second time Firebird
reported simply that ID is wrong, since no temporary blob exists.

Now, why didn't JayBird complain earlier? That's a bug, you should have
something "Not all parameters were set" or something similar. Please fill a
bug report and I will take care of it before JayBird 2.0 is out.

Roman