Setting up HSQL and Hibernate for Unit tests

Christian Decker wrote this late at night:
I know, this sounds a bit too specific to really bother you but since it’s a nice thing to do, and I use it really often during development I thought I’d share it with you.

The scenario

You are developing an application where you heavily rely on a database and want it to be tested during your unit tests. In my case I have an application that uses Hibernate that is connected to an Oracle database for it’s data persistence. Now I want to write some Unit Tests, using JUnit, to see wether all works fine and my objects get serialized and restored correctly. Usually I would have to set up another database with my structure and then test it on that, but JUnit explicitly discourages this as it requires you to setup the same environment on all machines that will test the code.

The solution

The solution is HSQLDB. HSQLDB is the leading SQL relational database engine written in Java. It has a JDBC driver and supports a rich subset of ANSI-92 SQL (BNF tree format) plus SQL 99 and 2003 enhancements. Along many other features it can also run in a memory resident mode, that will keep all of its data in memory and it is lost after the execution finishes. At first sight this may seem a useless feature, but think about what exactly you need when running unit tests: a simple to set up database, that is freshly instantiated with every run. And HSQL is easy to set up, in fact so easy that a single line makes all the difference.
So what once was my hibernate configuration file:
 
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC 
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@hostname:1526:orcl</property>
        <property name="connection.username">username</property>
        <property name="connection.password">password</property>
        <property name="connection.pool_size">10</property>
        <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="cache.provider_class">org.hibernate.cache.SwarmCacheProvider</property>
        <property name="show_sql">true</property>
        <mapping resource="events/Event.hbm.xml">
    </mapping>
</session-factory>
</hibernate-configuration>
Now becomes this:
 
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC 
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="connection.url">jdbc:hsqldb:mem:somename</property>
        <property name="connection.username">sa</property>
        <property name="connection.password"></property>
        <property name="connection.pool_size">1</property>
 
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
 
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
 
        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
 
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
 
        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">create</property>
 
        <mapping resource="events/Event.hbm.xml">
    </mapping>
</session-factory>
</hibernate-configuration>
Special attention is needed with the connection.url property and the hbm2ddl.auto property which tell hibernate to use a memory resident HSQL Database and to create the database structure at startup, which is exactly what we need for our Unit-Tests. Now for this to run you only need to include the HSQLDB Jar in your classpath and everything will run as it used to, only that it is much easier to test in a new environment, thus making it perfect for continouuous integration.
To sum it all up here are the steps to migrate to HSQL for testing:
  1. Add HSQLDB to your classpath
  2. Set the driverclass to org.hsqldb.jdbcDriver
  3. Set the dialect to org.hibernate.dialect.HSQLDialect
  4. Set the database URL to jdbc:hsqldb:mem:somename
  5. Run your tests :)




powered by performancing firefox

JavaScript Persisten Object Notation (JSPON)

Christian Decker wrote this just before lunchtime:
Some days old but still great news: Kris Zyp has written up an RFC for JSPON, a Notation for persisting objects over JSON. In “classical” JSON you have no way to reference the same object in different places (in fact there is no way to tell that two objects are actually the same) which leads to data redundancy. JSPON uses a similar approach to Java and DWR, every object that is being transferred gets an object id, which uniquely identifies it.
In order to identify JSON objects, a po$id field should be set to associate an “id” with the object. By identifying an object, it can now be referenced by id. The id field should be a string. For example:
{"po$id" : "34",
"myField" : "value"
"myChild": {"po$id" : "23"}
}
The advantages of this are easily spotted: you can now reference the same object multiple times, make cyclic relations and much much more. Especially the fact that we eliminate to repeat objects multiple time helps reducing communication size and therefore speed it up (a lot ^^).

Basic JSON does not support object referencing.  Therefore the following object (”obj”) could not be serialized with JSON:

var obj={};
var obj2 = {"foo": "val", "bar" : 4};
obj.field1 = obj2;
obj.field2 = obj2;

With JSON there is no way to communicate the fact that both field1 and field2 point to the same object. The best JSON could do is to make a copy of the serialization of obj2 for each field, but this does not effectively communicate that it is the same object and if you set obj.field1.foo = “newValue”, that obj.field2.foo should return “newValue”.  With JSPON this referenced can be communicated:

var obj={"po$id": "1", 
"field1": {"po$id": "2", "foo": "val", "bar": 4},
"field2": {"po$id": "2"}}
The RFC also defines some more advanced things such as lazy loading capabilities (po$ready), distributed object management (po$sourceURL), object versioning (po$version) and array and wrapper objects.

It’s really an interesting read and if it really becomes standard it may improve both speed and usability. Hopefully it is included in some of the popular libraries soon.
aaa


Technorati Tags: , , ,

JS Linker in Dojo Toolkit

Christian Decker wrote this mid-morning:

AOL has been very generous by donating code for the JS Linker for Dojo:

The JavaScript source code can be represented in different levels of granularity. The JavaScript Linker uses the Abstract Syntax Trees (ASTs) representation, which represents the lowest level of detail, to model the source code. One of the main task for this project was to write a JavaCC compatible grammar that strictly follows the ECMA Specification. JavaCC uses this grammar to build a custom parser than can read and analyze the JavaScript source, which in turn, is used to build the JavaScript Linker.

What this means to Alex Russell:

This is the holy grail of JavaScript optimization: removing “dead” code. Dojo already provides a package system to help prevent including too much and a build-time compressor to help reduce the size on the wire of what you do need, but the linker does all of this one better by analyzing the application and figuring out what functions are entirely unused.

JavaScript has some unique issues with packaging, and this will help Dojo coders out a lot.



Technorati Tags: , ,