Issues with JBCP and Sybase

Posted by lee on February 9th, 2009

BCP is a method for quickly copying data into SQL Server or Sybase databases. It’s much faster than running INSERT statements, so if you have a large amount of data, it’s a tempting option.

However, the trade-off for the speed is that when importing data, it bypasses a large amount of error checking and handling. As a result, any error messages you do get from the database server can often be cryptic or can even appear to be unrelated to what you’re trying to accomplish!

As well as the command-line BCP tool, JBCP is a pure Java library that reimplements the BCP protocol for Java developers. Unfortunately it’s still relatively immature, and you may find that Sybase gives the following error message in response to almost all JBCP issues:

Bad row data received from the client while bulk copying into object 1874356894 in database 4

This can be caused by several things. The most common is simply that the table definition has not been setup correctly to allow rows to be BCP’d into it. One way to resolve the issue is to ensure that the table you are copying into has ‘lock allpages’ as part of its definition, for example:

CREATE TABLE bcptest (some_key int not null, mydata varchar(50) null) lock allpages
go

Other issues can be caused by using univarchar columns that exceed 255 bytes. This means that all univarchar columns you attempt to copy into must be no larger than univarchar(127). A valid workaround for this issue is to split large column definitions into several smaller columns, and then use an UPDATE statement to reassemble the data from the split columns after it has been uploaded.

To help googlers, here is the complete stack trace I was typically seeing from JBCP before I created my table with the additional lock allpages clauses.

java.sql.SQLException: Bad row data received from the client while bulk
copying into object 1874356894 in database 4. Received a row of length
72 whilst maximum or expected row length is 15.
[19/12 10:46:37.160] [TID:lee2BCP1]:Upload of 1 result: FAILED
       at
net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:368)
       at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:3149)
       at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2587)
       at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:734)
       at net.sourceforge.jtds.jdbc.TdsCore.bcpBatch(TdsCore.java:2394)
       at net.sourceforge.jtds.jdbc.BCP.bcpBatch(BCP.java:1134)
..snip..

One final warning for using JBCP - you don’t always even see the problem by default - some exceptions are supressed causing silent failure! There be dragons!

Java JSP code example: A Facebook “invite your friends” panel

Posted by lee on February 22nd, 2008

When developing a Facebook application, there are plenty of platform integration points to consider. One of the most essential is the invite panel. This is where users will share your application with their friends. If there’s a bug in your invite panel, your application will never be able to “go viral” and take over world.

Technically, the official documentation does accurately describe the requirements for creating an invite panel. However, I found several gotchas when creating one, so provide the following example in JSP for interested readers. (Notes and screenshots below).

1
2
3
4
5
6
7
8
9
10
11
12
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 
<c:set var="invite">
  You can use Friends Connection to introduce me to your other friends.
  I can't wait to meet and chat with them!
  &lt;fb:req-choice url='http://apps.facebook.com/friendsconnection/index.htm' label='Make new friends' /&gt;
</c:set>
 
<fb:request-form type="friends connection" content="${invite}" invite="true"
                 action="http://apps.facebook.com/YOURAPPHERE/index.htm">
  <fb:multi-friend-selector rows="4" actiontext="Connect yourself with your friends' friends" />
</fb:request-form>

The JSP above will create the following invite panel, (friend names blacked-out for privacy):

Facebook Invite Panel

Most of this panel is as it will appear for your own application, (albeit with different friend pictures!) The following items are easy to customize:

  1. The main heading
  2. The text on the invite button
  3. The text that will be sent to prospective application users, (ie. the invitation panel shown below).
  4. The request form “type” - this is a small phrase that identifies your application

If you want to preview how the invite will look on the ‘requests’ page of prospective users, select any friend and click the button; the panel will appear as below:Facbeook Invite Panel with an “invite” button

Customizing the “You have an XXXXX invitation.” panel is filled with gotchas. At first glance it appears simple - you add some text using the content attribute of fb:request-form. However, it’s easy to miss the fact you must add the invite buttons to that attribute as well, in FBML format! And they must be entity-escaped to be valid XML!

To make this in a maintainable way, you can set a page request variable using c:set, and simply escape the < and > symbols into &lt; and &gt; yourself. Using single quotes for the fb:req-choice attributes avoids the need to escape double quotes.

The easiest thing to do is copy and paste the code example above, try it out, tweak it and try it some more. If you’re still at a loose end, try the official documentation pages for fb:request-form, and fb:req-choice (though don’t get side-tracked by fb:request-submit-button as it is not relevant).

If you’re still having trouble, or have any suggestions of your own to make this process a little simpler, please drop your comments in the box below.




© 2009 Lee Mallabone
Powered by Wordpress. Theme provided by Wordpress Themes - Absoluteshield Internet Eraser