All entries for Friday 09 December 2005

December 09, 2005

Serializing java objects to Oracle

We recently had a requirement to use our new Shibboleth based Single Sign On system with a cluster of jboss servers running an essentially stateless application.

The way that our new SSO works is through the SAML Post Profile meaning that an authentication assertion is posted by the user to the Shire service. This shire service then does an Attribute Request back to SSO and puts the results into a user cache in memory and generates a cookie which links to the user in the cache.

The problem is that the request might then go back to another member of the cluster which does not share the cache so it won't know about the user represented by the cookie. The obvious solution is some kind of clustered cache.

We've not needed to use any clustered cache technology before so passed on the likes of Coherence (insane pricing) and other open source caches such as memcached. It is best not to introduce new technologies that you can't support unless you have to.

I ended up building a simple two level cache that put the data both in memory and in the database. If when a request came in, there was nothing in the memory cache, it checked the database and populated the memory cache. I wouldn't want to go to the database everytime as this is a very busy application that could do without the additional overhead.

Now, the code.

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(baos);
oos.writeObject(value);
} catch (IOException e) {
throw new RuntimeException("Could not write object to stream",e);
}

SqlUpdate su = new SqlUpdate(getDataSource(), "INSERT INTO objectcache " + "(key, objectdata,createddate) "
+ "VALUES (?, ?,?)");
su.declareParameter(new SqlParameter("key", Types.VARCHAR));
su.declareParameter(new SqlParameter("objectdata", Types.BLOB));
su.declareParameter(new SqlParameter("createddate", Types.DATE));
su.compile();

Object[] parameterValues = new Object[3];
parameterValues[0] = key.toString();

LobHandler lobHandler = new DefaultLobHandler();
parameterValues[1] = new SqlLobValue(baos.toByteArray(), lobHandler);

parameterValues[2] = new java.sql.Date(new Date().getTime());

su.update(parameterValues);
Not knowing how big these objects were going to be, I figured it would be best to put this in a blob, but that has its own joys, especially with plain old JDBC. I used Spring's very handy JDBC helpers to make my life easier. If you want to get the object back out:
ObjectInputStream ois = new ObjectInputStream(new DefaultLobHandler().getBlobAsBinaryStream(resultSet, 1));
UserCacheItem dbItem = (UserCacheItem) ois.readObject();
return dbItem;
Basically just select back the object and use the ObjectInputStream to de-serialize the object back into existence. Simple.

December 2005

Mo Tu We Th Fr Sa Su
Nov |  Today  | Jan
         1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31   

Tags

Search this blog

Most recent comments

  • One thing that was glossed over is that if you use Spring, there is a filter you can put in your XML… by Mathew Mannion on this entry
  • You are my hero. by Mathew Mannion on this entry
  • And may all your chickens come home to roost – in a nice fluffy organic, non–supermarket farmed kind… by Julie Moreton on this entry
  • Good luck I hope that you enjoy the new job! by on this entry
  • Good luck Kieran. :) by on this entry

Galleries

Not signed in
Sign in

Powered by BlogBuilder
© MMXIX