Tuesday, July 05, 2005

How to write a Java Object to a database blob column

This snippet describes how to write a Java Object to a database BLOB column, then read it back. The Java Object must be Serializable so that it can be represented as a byte array for either writing or reading.

First, writing to a blob column. For this example, there is a table called blobtable. It contains a BLOB colunm called blobcolumn. The way to write it to the DB is to assign the Serializable to a byte array, then write that byte array to the DB.


public void saveObjectToBlob(
        Connection conn,
        Serializable saveObject)
throws IOException, SQLException {

    PreparedStatement stmt = null;
    String query =
        "INSERT " +
        "INTO blobtable (" +
        " blobcolumn) VALUES (" +
        " ?) ";

    stmt = conn.prepareStatement(query);

    // write the object content to a byte array
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(saveObject);
    oos.close();
    byte saveObjectBy[] = bos.toByteArray();
    stmt.setBytes(1, saveObjectBy);
    // Oracle converts it to BLOB automatically

    stmt.executeUpdate();
}


After writing it to the blob column, you can read it back. The way to read it back is to use the Blob interface for the DB blob column. Read it back as byte array, then cast that to Serializable. Then cast the Serializable to the original Object type.


public Serializable readObjectFromBlob(Connection conn)
throws SQLException, IOException, ClassNotFoundException {

PreparedStatement pstmt = null;
ResultSet rset = null;
String query =
"SELECT " +
" blobcolumn " +
"FROM " +
" blobtable ";

pstmt = conn.prepareStatement(query);
rset = pstmt.executeQuery();
Serializable result = null;
if (rset.next()) {
byte blobcolumnBy[];
Blob bl = rset.getBlob(1);
blobcolumnBy = bl.getBytes(1, (int) bl.length());

ByteArrayInputStream bis =
new ByteArrayInputStream(blobcolumnBy);
ObjectInputStream ois = new ObjectInputStream(bis);
Object obj = ois.readObject();
ois.close();
result = (Serializable) obj;
}

return result;
}

Monday, July 04, 2005

Brown, J2EE, tractor trailer

I recently was working on an application that was Servlet based in Tomcat. That was pretty good. It was nice to be able to roam around the Java language and libraries and do stuff with threads and such.

Before this most of my Java experience was EJB. I don't really like EJB. It seems annoying a lot of the time with its rules and restrictions. And it's so verbose and so much overhead getting things deployed and callable. We've had some success using XDoclet to auto-generate some of the verbiage, but it's still big. We're not even using entity beans, thankfully; that would be just so much more overheads.

We have to be quick to get things done on aggressive schedules and be able to modify existing systems for new requirements. Sometimes with J2EE it seems like we're a courier trying to deliver packages in the downtown business district using a tractor trailer. The big rig is scalable; you can load all kinds of heavy freight on it, but in the downtown during the daytime it is so bulky that it has trouble navigating the traffic, changing direction or parking. For the traffic congested downtown you'd be better with one of the UPS brown vans, which carry a big enough load, but can move around better in thick traffic and tight parking and can change direction easily based on how business unfolds that day.

Now if you're moving say 40 brand new large sofas from a warehouse in Montreal to a furniture store in Sydney then the tractor trailer is the best vehicle to use. You can fit them all in one load, and the rig manages the long highway miles easily.

Looking at it that way, it makes me sometimes get down a bit on J2EE. But thinking about it more, I think my gripe is more with EJB than with the full J2EE. After all I know I like the Servlets stuff. EJB just seems to suck up the joy of programming at times.

I know I'm not the only one who isn't excited about EJB. When people write entire books about J2EE without EJB then there are many others too who want to use J2EE but are turned off by EJB. Still with J2EE, especially EJB the specs are just eye glazing. Even a book like the 21 days that tries hard to be accessible and reader friendly is painful to read when they necessarily delve into the J2EE specs and rules. I wish the concepts and terminology could be somehow simplified.

I always thought that EJB was a necessary evil to obtain scalability. Turns out that's not so. walmart.com was built using just Apache and Tomcat servlets. Apparently no need for EJB to achieve performance, security, etc. I find that very interesting.

So if we don't need it to get scalability then maybe we'd be better off without EJB. Just use servlet - which I've found well thought through and agreeable to work with - plus a much more lightweight framework, or maybe no real extra framework. That idea appeals to me. I'll get to work with Tomcat and servlet for a bit longer on this project, I'm not real excited about going back to EJB.

Tuesday, June 14, 2005

SAS

I like to read ComputerWorld Canada, especially since I get it for free. Every few weeks or so they have an article where they mention SAS. They always seem to have something good to say about them.

Like this recent article about software quality where they use SAS as a positive example of a software company where quality is a priority. Go to ITWorldCanada, enter code 050562 in the quick link, regrettably there's a one-time free registration, then a couple more clicks to the article.

Based on the ComputerWorld Canada articles, it seems like SAS would be a great place to work as a developer: focus on quality led by the CEO, privately held so less of the quarterly shenanigans, hiring during a down period because there was good talent floating around after the dot com bust. They seem to show that you can do software "right" and still be successful.

If I was single and more free to relocate I think I'd want to apply to work there.

Tuesday, June 07, 2005

Oracle PL/SQL function to get current time in UTC

This snippet is an Oracle PL/SQL function that returns the current timestamp in the UTC time zone. It takes advantage of the EXTRACT Oracle built in returning its result in UTC.

FUNCTION getUTCDate RETURN DATE
AS
  utcYear NUMBER(4);
  utcMonth NUMBER(2);
  utcDay NUMBER(2);
  utcHour NUMBER(2);
  utcMinute NUMBER(2);
  utcSecond NUMBER(2);
  dateString VARCHAR2(30);
  ts TIMESTAMP WITH TIME ZONE;
BEGIN
  ts := SYSTIMESTAMP;
  utcYear := EXTRACT(YEAR FROM ts);
  utcMonth := EXTRACT(MONTH FROM ts);
  utcDay := EXTRACT(DAY FROM ts);
  utcHour := EXTRACT(HOUR FROM ts);
  utcMinute := EXTRACT(MINUTE FROM ts);
  utcSecond := TRUNC(EXTRACT(SECOND FROM ts));
  --
  dateString := TO_CHAR(utcYear) || ':' ||
                TO_CHAR(utcMonth) || ':' ||
                TO_CHAR(utcDay) || ':' ||
                TO_CHAR(utcHour) || ':' ||
                TO_CHAR(utcMinute) || ':' ||
                TO_CHAR(utcSecond);
  RETURN TO_DATE(dateString, 'yyyy:mm:dd:hh24:mi:ss');
END getUTCDate;

Monday, June 06, 2005

The source of your source code

In the recent death march project, I was responsible a large block of inherited code. I don't mean inherited in the object oriented sense. I mean that the code was written by a different office and transferred to our office for use in the project. The intention was that by reusing the original code we could save time against building the module ourselves and help to meet the project schedule.

We would be using the inherited code using a slightly different workflow than the original deployment. Also we were switching the environment from Windows server to Solaris. Since it's Java it didn't need to be modified for platform.

Unfortunately in testing there were a some problems in the inherited code. I had to pull some all-nighters to fix some issues. hint: with servlet you need to be really careful about thread safety. hint2: well placed source comments can greatly assist someone who is not the original developer who may be maintaining your code in the future.

So it goes. Hard experience gained. Going forward we now have a track record from that office and if a future situation like this arises then can know what to expect and can better plan for how to deal with it.

It may be that every line of code you write is a liability. However every line of code you inherit from outside sources is a risk. In general, deal with widely used sources that have a good reputation like Apache. Whether internal from your organization or external from the Internet, be careful of code from previously unused sources. Be aware of the risk that the code will not perform as expected. Integrate it early, to allow the most time for testing and to deal with problems which may occur.

Thursday, June 02, 2005

Tech support dilemma

A former co-worker once described tech support from a large, well-known software vendor like this: "I found it was better to stand in front of a mirror and describe the problem to myself than to try to get help from XYZ support."

Why is tech support generally bad? The problem may be that once people get to a point where they can be effective at it, then they are at a point where they can be better used elsewhere. Suppose individual X does tech support for a large, complex software product; say a GIS system.

X is good at it, with deep understanding of the underlying specifications, full knowledge of the intricacies and glitches of the product in several functional areas, ability to quickly read customers (generally incorrect) source code and fix problems, communicates well with customers, etc.

What then becomes of X? Probably X will be transferred out of tech support into the consulting, testing or programming groups. In the consulting group the XYZ company can charge more for X's skills. In testing or programming X can bring a greater good than in tech support. In support you can basically help one person at a time and a fixed limited number overall. In the programming or test teams, you advance the product, which benefits everyone who uses the product. Thus more people benefit from X's efforts which should be more profitable to XYZ corp.

X's employer could decide to keep X in tech support because she is very good at it and her customers are happy. However this probably won't last because X can take her skills to a promotion out of tech support at a different company. So if XYZ doesn't promote X out of tech support then another company will.

So this may be why tech support is often bad. Once people get good at it they can be reassigned to more profitable areas. Also because of the cost and learning curve around big, complex software systems, it is better to keep around those tech support who aren't very good because turnover is expensive and the new replacements you bring in generally won't be better than those they are replacing.