Mathew, Actually, the SELECT FOR UPDATE would have little to do with the driver as it's a direct SQL call. Also, it seems the getter method does fully retrieve the lobs. The problem I'm referring to happens on insert/update. I'll send out a message on this shortly.
Michael ----- Original Message ----- From: "Matthew Baird" <[EMAIL PROTECTED]> To: "OJB Users List" <[EMAIL PROTECTED]> Sent: Friday, November 22, 2002 1:58 PM Subject: RE: [PATCH]Re: null value for Blob/Clob causes NullPointerException the problem I see with this is, you could write an oracle specific blob/clob implementation and put it in the platform impl, but in a lot of cases that would be specific to the driver and not necessarily Oracle. The solution would be to have a driverplatform, which isn't a good idea either as many jdbc classes are wrapped (both by ojb and potentially by your app server, say Jboss). There is not a reliable way to find out what the driver is, and therefore cast to the appropriate ORACLE jdbc type to accomplish the insertion. I haven't seen anyone do a great job with this. m -----Original Message----- From: Michael Mogley [mailto:[EMAIL PROTECTED]] Sent: Friday, November 22, 2002 1:38 PM To: OJB Users List Subject: Re: [PATCH]Re: null value for Blob/Clob causes NullPointerException Russell, Thanks for addressing this so quickly. Another thing I'm concerned about is how Ojb handles LOBs that are larger than 4K - particularly for insert/update. On Oracle, I know that a SELECT FOR UPDATE is required on the LOB field, after which an OutputStream is opened and written to. At least this is what I have had to do with the 8.1.7 thin drivers. I have found that attempting to store a string directly using the conventional PreparedStatement.set(int, Object) method causes it to be truncated after 4K. I'll do some tests today to see what the case is with Ojb. Just wanted to give you a heads-up on the issue. Michael ----- Original Message ----- From: "Russell Smyth" <[EMAIL PROTECTED]> To: "'OJB Users List'" <[EMAIL PROTECTED]> Sent: Friday, November 22, 2002 10:41 AM Subject: RE: [PATCH]Re: null value for Blob/Clob causes NullPointerException > I am sorry, I did not realize you do not know how to read or apply a patch. > The code you > quote is the original, un-patched code. Let me walk you through the patch. > > (PATCH HEADER INFO - DESCRIBES THE PATCH) > Index: src/java/org/apache/ojb/broker/accesslayer/JdbcAccess.java > > =================================================================== > RCS file: > /home/cvspublic/jakarta-ojb/src/java/org/apache/ojb/broker/accesslayer/JdbcA > ccess.java,v > retrieving revision 1.21 > diff -u -r1.21 JdbcAccess.java > --- src/java/org/apache/ojb/broker/accesslayer/JdbcAccess.java 14 Nov 2002 > 20:28:20 -0000 1.21 > +++ src/java/org/apache/ojb/broker/accesslayer/JdbcAccess.java 22 Nov 2002 > 05:08:08 -0000 > @@ -582,13 +582,13 @@ > (SOME CONTEXT TO SEE WHERE THE PATCH GOES, AND TO ALLOW THE PATCH TOOL TO > INTEGRATE THE CHANGE - THIS "UN MARKED" CODE IS COMMON TO BOTH BEFORE AND > AFTER) > case Types.CLOB : > { > java.sql.Clob aClob = rs.getClob(columnId); > (A "REMOVE LINE" INDICATOR, MEANING REMOVE THIS LINE FROM THE ORIGINAL, AT > THIS POSITION) > - result = aClob.getSubString(1L, (int) aClob.length()); > (A "ADD LINE" INDICATOR, MEANING ADD THIS LINE TO THE ORIGINAL, AT THIS > POSITION) > + result = ( rs.wasNull() ? null : aClob.getSubString(1L, > (int) aClob.length()) ); > break; > } > case Types.BLOB : > { > java.sql.Blob aBlob = rs.getBlob(columnId); > - result = aBlob.getBytes(1L, (int) aBlob.length()); > + result = ( rs.wasNull() ? null : aBlob.getBytes(1L, > (int) aBlob.length()) ); > break; > } > default : > > > I hope this clears things up for you. As you can see, in my code > result = ( rs.wasNull() ? null : aClob.getSubString(1L, (int) > aClob.length()) ); > we do nothing with the blob/clob if it is null, just return null! > > Russell > > -----Original Message----- > > From: Rajeev Kaul [mailto:[EMAIL PROTECTED]] > > Sent: Friday, November 22, 2002 11:35 AM > > To: OJB Users List > > Subject: Re: [PATCH]Re: null value for Blob/Clob causes > > NullPointerException > > > > > > Your code will crash at the point where you are using the > > clob/blob object > > without checking if it is null. For example, at the > > following statement: > > > > result = aClob.getSubString(1L, (int) > > aClob.length()); > > > > Now, I have not checked what happens if the CLOB field is of > > zero length but > > not null. If it is possible to have a zero-length CLOB field > > then we just > > check for CLOB object being null and remove the check for its length. > > > > ----- Original Message ----- > > From: "Russell Smyth" <[EMAIL PROTECTED]> > > To: "'OJB Users List'" <[EMAIL PROTECTED]> > > Sent: Friday, November 22, 2002 10:21 AM > > Subject: RE: [PATCH]Re: null value for Blob/Clob causes > > NullPointerException > > > > > > > I fail to se how your change is different, except that your > > change will > > > leave the return value as null if the CLOB/BLOB length is 0 > > - which I > > think > > > is incorrect. > > > If the db reports that the CLOB/BLOB is there but empty, > > then it is NOT > > > null. > > > > > > my change returns null if the db reports null, and reports > > the value of > > the > > > BLOB/CLOB as reported by the db if not null. > > > > > > Your other changes I would have to look through the sources > > to see what > > you > > > intend. Diffs would be much easier to read here! > > > > > > -----Original Message----- > > > From: Rajeev Kaul [mailto:[EMAIL PROTECTED]] > > > Sent: Friday, November 22, 2002 11:11 AM > > > To: OJB Users List > > > Subject: Re: [PATCH]Re: null value for Blob/Clob causes > > NullPointerException > > > > > > > > > I do not think your patch addresses the problem of either > > CLOB or BLOB > > > object being null. The fix that worked for me is shown below: > > > > > > case Types.CLOB : > > > { > > > java.sql.Clob aClob = rs.getClob(columnId); > > > if (aClob != null && aClob.length() > 0) > > > { > > > result = > > > aClob > > > .getSubString(1L, (int) > > aClob.length()) > > > .toCharArray(); > > > } > > > break; > > > } > > > case Types.BLOB : > > > { > > > java.sql.Blob aBlob = rs.getBlob(columnId); > > > if (aBlob != null && aBlob.length() > 0) > > > { > > > result = aBlob.getBytes(1L, (int) > > aBlob.length()); > > > } > > > break; > > > } > > > > > > > > > I had earlier submitted fixes for other CLOB issues. I am > > resending them > > in > > > case somebody finds them useful. > > > > > > To fix the problem, I made the following changes: > > > > > > 1. Modified ojbtest_schema.xml BLOB_TEST table to (the > > changes are shown > > in > > > Red). > > > > > > <table name="BLOB_TEST"> > > > <column name="ID" required="true" primaryKey="true" > > type="INTEGER"/> > > > <column name="BLOB_VALUE_" type="BLOB"/> > > > <column name="CLOB_VALUE_" type="CLOB"/> > > > </table> > > > > > > 2. Modified the setObjectForStatement method of > > PlatformOracleImpl class > > to > > > write CLOB data as shown below: > > > > > > > > > public void setObjectForStatement(PreparedStatement ps, int > > index, Object > > > value, int sqlType) throws SQLException > > > > > > { > > > > > > if (((sqlType == Types.VARBINARY) || > > > > > > (sqlType == Types.LONGVARBINARY) || > > > > > > (sqlType == Types.BLOB)) && > > > > > > (value instanceof byte[])) > > > > > > { > > > > > > byte buf[] = (byte[])value; > > > > > > ByteArrayInputStream inputStream = new > > ByteArrayInputStream(buf); > > > > > > changePreparedStatementResultSetType(ps); > > > > > > ps.setBinaryStream(index, inputStream, buf.length); > > > > > > } > > > > > > else if (sqlType == Types.CLOB) > > > > > > { > > > > > > CharArrayReader inputStream = new > > CharArrayReader((char[]) value); > > > > > > ps.setCharacterStream(index, inputStream, > > ((char[])value).length); > > > > > > } > > > > > > else if (value instanceof Double) > > > > > > { > > > > > > // workaround for the bug in Oracle thin driver > > > > > > ps.setDouble(index, ((Double) value).doubleValue()); > > > > > > } > > > > > > else > > > > > > { > > > > > > super.setObjectForStatement(ps, index, value, sqlType); > > > > > > } > > > > > > } > > > > > > 3. In JdbcAccess class modified the getObjectFromColumn method for > > CLOB/BLOB > > > to what is shown at the top of this e-mail. > > > > > > > > > > > > The CLOB should return an object of type char[] to be > > consistent with > > BLOBs > > > returning objects of type byte[]. However, it is not > > mandatory to do so. > > > We could leave this as is, and modify the CLOB fields in > > corresponding > > > classes to be of type String. That is, for example, the > > ObjectWithBlob > > > class will have to be modified to have the clob property > > defined as a > > > String. But if we make the change shown above, you do not > > have to modify > > > the ObjectWithBlob class - the clob property can remain as character > > array. > > > > > > > > > ----- Original Message ----- > > > From: "J. Russell Smyth" < <mailto:[EMAIL PROTECTED]> [EMAIL PROTECTED]> > > > To: "OJB Users List" < <mailto:[EMAIL PROTECTED]> > > > [EMAIL PROTECTED]> > > > Sent: Thursday, November 21, 2002 9:51 PM > > > Subject: [PATCH]Re: null value for Blob/Clob causes > > NullPointerException > > > > > > > > > > We just happened to also run into that today. > > > > > > > > Attatched is a patch to fix, and a patch to the test case > > for blobs to > > > > verify the fix. Unfortunately HSQLDB does not support the blob > > > > functions, hence this test is commented out of AllTests, > > and I do not at > > > > the moment have access to my other db's to run this test. > > However, it > > > > should be good. > > > > > > > > On Thu, 2002-11-21 at 20:11, Michael Mogley wrote: > > > > > I've just started experimenting with Ojb and seem to > > have run across a > > > bug. Specifically, a Clob or Blob field whose value is > > undefined in the > > db > > > gives the following stack trace: > > > > > > > > > > java.lang.NullPointerException > > > > > at > > > > > org.apache.ojb.broker.accesslayer.JdbcAccess.getObjectFromColu > > mn(JdbcAccess. > > > java:592) > > > > > at > > > > > org.apache.ojb.broker.accesslayer.JdbcAccess.getObjectFromColu > > mn(JdbcAccess. > > > java:469) > > > > > at > > > > > org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl.readObj > > ectArrayFrom(R > > > owReaderDefaultImpl.java:141) > > > > > at > > > > > org.apache.ojb.broker.accesslayer.RsIterator.getObjectFromResu > > ltSet(RsIterat > > > or.java:385) > > > > > at > > > > > org.apache.ojb.broker.accesslayer.RsIterator.next(RsIterator.java:203) > > > > > at > > > > > org.apache.ojb.broker.singlevm.PersistenceBrokerImpl.getCollec > > tionByQuery(Pe > > > rsistenceBrokerImpl.java:1117) > > > > > at > > > > > org.apache.ojb.broker.singlevm.PersistenceBrokerImpl.getCollec > > tionByQuery(Pe > > > rsistenceBrokerImpl.java:1239) > > > > > at > > > > > org.apache.ojb.broker.singlevm.PersistenceBrokerImpl.getCollec > > tionByQuery(Pe > > > rsistenceBrokerImpl.java:1265) > > > > > at > > > > > org.apache.ojb.broker.singlevm.PersistenceBrokerImpl.getCollec > > tionByQuery(Pe > > > rsistenceBrokerImpl.java:1252) > > > > > > > > > > Ojb attempts to perform operations on the Blob/Clob > > before checking to > > > see if the returned value is null. > > > > > > > > > > Or am I missing something? > > > > > > > > > > Michael > > > > > > > > > > > > > > > > > > > > > > > _____ > > > > > > > > > > > > > > > > -- > > > > To unsubscribe, e-mail: < > > > <mailto:[EMAIL PROTECTED]> > > > mailto:[EMAIL PROTECTED]> > > > > For additional commands, e-mail: < > > > <mailto:[EMAIL PROTECTED]> > > > mailto:[EMAIL PROTECTED]> > > > > > > > > > > > > -- > > To unsubscribe, e-mail: > > <mailto:[EMAIL PROTECTED]> > > For additional commands, e-mail: > > <mailto:[EMAIL PROTECTED]> > > > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>