Derby and Hibernate are each very large packages full of power and fraught with complexities. When I first started working with them, I desperately wanted a very simple mechanism that would handle the basic drudgery so that I could concentrate on writing my application. The led me to the creation of a fairly small class (~300 lines) that did everything that I needed.

Please see the DatabaseManagerSource and the DatabaseUtilitiesSource.

I have learned that there is one troublesome issue with this implementation. Each class defined to be handled by Hibernate requires several seconds worth of initialization and in some instance, this can be fatal. I was trying to use it in a web application. At first, I had the DatabaseManager being created by the first page access - and that made the first page access very slow. Next I tried adding an initialization call to the "init" method of one of the servlets. That caused the "enable" to time out. Eventually what I found that worked was putting the initialization in a seperate thread. The initialization was started by the "init" method of one of the servlets and by the time I was ready to get the first page, things were usually good to go - but regardless, there weren't any ugly or fatal timeouts.

When I have the web app in question up, running and reasonably stable, I will probably put that version of the DatabaseManager up.

Configuration Files

The glue that makes everything work is the configuration files. A Hibernate file for each class (MyClass.hbm.xml) and a DatabaseManager.xml file (in the same package as the DatabaseManager class).

The DatabaseManager XML file consists of a root element and three child elements, Classes, createSql and Initialization.

The Classes element is a list of "Class" elements containing the fully qualified class name of a class that you want to persist. The createSql element is a list of "statement" elements containing the SQL statements that will be used to create the database. The Initialization element is a list of "Load" elements for which the Derby procedure SYSCS_IMPORT_DATA will be called.

The only catch with this initialization feature is that in order for it to work, you must write a static function "setContext()" that will initialize a path variable for the table files.

<DatabaseManager>
    <Classes>
        <Class>com.pig.Oink</Class>
        <Class>com.dog.Bark</Class>
    </Classes>

    <createSql>
        <statement>
            sql to create table for Oink class goes here
        </statement>

        <statement>
            sql to create table for Bark class goes here
        </statement>
    </createSql>

    <Initialize>
        <Load>
            <Table>OINK_TABLE</Table>
            <Columns>OINK_COLUMN1, OINK_COLUMN2, OINK_COLUMN3</Columns>
            <File>PATH_TO_OINK_FILE</File>
        </Load>
    </Initialize>
</DatabaseManager>

Example

Using a DatabaseManager is fairly simple.

        DatabaseManager.setContext("my parameters go here");

        File dbFile = new File("PropertySetTest");
        DBUtilities.deleteAnyFile(dbFile);

        DatabaseManager dbm = new DatabaseManager(dbFile);
        Session session = dbm.getMainSession();

This is an example from a test class. It deletes the database at the beginning of the test so that 1) the database will be created with the latest schema and 2) the database will start at a known state (empty).

  • No labels