ADBCJ in Scala: Getting Started

What, again asynchronous database access? Yes, because I’m currently knee deep in this stuff. (^^) This post series will show how to use ADBCJ in Scala 2.10, share a few tips, performance insights etc.

ADBCJ and Scala, new buddies

ADBCJ and Scala, new buddies

Grabbing the Bits

Of course, first we need to grab the bits. We can get it via SBT. Currently there are only snapshots available on my snapshot repository. We pull the Scala ADBCJ API, the ADBCJ connection pool and the MySQL driver.

Getting Access to the Database

The next step is to get access the the database. We do this with the Database object, by passing in the connection URL, username and password. This create a instance which is used to access this database. Usually you should have one instance only per database in your application.

Then we can create new connections. The most basic way is to create a connection directly. However, you are then responsible for closing the connection.

Closing Connections Automatically

Now closing the connection manually can be error prone and tedious. Therefore helper methods exists. One for using a connection and one for using a connection with a new transaction.
The closure has to return a future. Since everything is asynchronously, we cannot close the connection when we leave the future. Instead we need to close it when everything is done. So, the connection will be close, when the future returned by the closure is completed.

Some Real Work

Let’s do some real work. We create the schema if it doesn’t exist and then insert a few items. In general, I highly recommend to read the Akka documentation about futures, which gives an idea how to deal with tem.

Query

Let’s also query for some data. When running queries, your future will contain a immutable result set, which supports the standard collection operations.

Prepared Statements

Of course, there prepared statement support:

One Last Hint, Debugging

So, this was a small tour through the API. However I want to share one last important thing, which helps you dealing with failures.

Let’s assume you ran a back query:

org.adbcj.mysql.codec.MysqlException: 42S02Table 'adbcj-demo.thistabledoesnotexist' doesn't exis 
  at org.adbcj.mysql.codec.packets.ErrorResponse.toException(ErrorResponse.java:49)
	at org.adbcj.mysql.codec.decoding.ExpectQueryResult.handleError(ExpectQueryResult.java:31)
	at org.adbcj.mysql.codec.decoding.ResponseStart.parse(ResponseStart.java:33)
	at org.adbcj.mysql.codec.decoding.AcceptNextResponse.parse(AcceptNextResponse.java:26)
	at org.adbcj.mysql.codec.MySqlClientDecoder.doDecode(MySqlClientDecoder.java:96)
	at org.adbcj.mysql.codec.MySqlClientDecoder.decode(MySqlClientDecoder.java:67)
	at org.adbcj.mysql.netty.Decoder.decode(MysqlConnectionManager.java:177)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:113)
	...

Then you get a future which contain the error. However, the stack trace of the error does not contain any hint where in the code the query was issues. It just contains a stack trace with the internal event loop:

You can use the debug flat to get a stack trace which points at the location which sent the request. Either add -Dorg.adbcj.debug=true to the JVM flags. Or set the appropriate property when crating the database access. Note that this feature is quite expensive, so I recommend to use it while developing or during an investigation.

So, that’s it for now. Future posts will go into more aspects of ADBCJ the interaction with Scala.