In-Memory Java DB 15.0.1.1 - Perfect For JPA-Unit testing

To install Java DB 10.5.1.1 you only have to download a ZIP file, extract it and put two JARs into your classpath. It comes with one major, killer feature - in-memory capability. I used Java DB for test purposes in embedded mode already. The database creates a folder in your local file system, what takes time and requires you to do some plumbing. This mode, however, is perfect if you needed a pre-populate database for your tests. You just had to copy the folder with an existing database into your test-project before your launch the tests and delete it afterwards.

With a in-memory connection: jdbc:derby:memory:sampledb;create=true you can create your database dynamically - and you don't even have to drop the tables afterwards.

To test it, I just adjusted the CRUD-Service configuration and measured the performance again. I didn't have to change anything in the unit-test:


public class CrudServiceBeanTest {

    private EntityManager em;
    private EntityTransaction et;
    private CrudServiceBean crudServiceBean;

    @Before
    public void setUp() throws Exception {
        this.em = Persistence.createEntityManagerFactory("test").createEntityManager();
        this.et = this.em.getTransaction();
        this.crudServiceBean = new CrudServiceBean();
        this.crudServiceBean.em = this.em;
    }
    
    @Test
    public void crud(){
        Book book = new Book("1", "Productive Java EE");

        this.et.begin();

        int initialSize = this.crudServiceBean.findWithNamedQuery(Book.ALL).size();
//... see CRUD Service Example

I only changed one line in the persistence.xml to switch from the embedded to the in-memory mode (Glassfish v2.1 with TopLink):

Embedded mode: <property name="toplink.jdbc.url" value="jdbc:derby:./testDB;create=true"/>

In-Memory mode: <property name="toplink.jdbc.url" value="jdbc:derby:memory:testDB;create=true"/>

In the In-Memory configuration you don't have to drop the tables or clean the database after the tests - it just disappears. You only have to create the tables before the tests. In Glassfish v2 with Toplink you can fall back to the following setting: <property name="toplink.ddl-generation" value="create-tables"/>.

The performance is significantly faster, also in this simple case. The embedded mode took:

Tests run: 3, Failures: 0, Errors: 0, Time elapsed: 2.997 sec

...and the same unit tests on in-memory database:

Tests run: 3, Failures: 0, Errors: 0, Time elapsed: 2.476 sec

H2 and HSQLDB have the in-memory capabilities for ages. Java DB, however, comes with more complete feature-set and is surprisingly DB 2 compatible. The working example was pushed into http://kenai.com/projects/javaee-patterns/ (DAOPattern).

[The code was originally published in this Real World Java EE Patterns book, Page 141 

Comments:

Just want to promote a small project i newly created to make unittesting JPA and JEE5 EJBs easier:

http://markatta.com/jee5unit

Uses HSQL and Hibernate though.

Posted by Johan Andrén on July 16, 2009 at 01:56 PM CEST #

Adam, I made some performance tests a few weeks ago. You can check http://agoncal.wordpress.com/2009/07/05/derby-10-5-1-1-is-really-an-in-memory-database/

Posted by Antonio Goncalves on July 16, 2009 at 02:08 PM CEST #

Nice! The lack of this feature took me previously to the H2 database system. I'll give JavaDB another look then.

Posted by Jamie on July 16, 2009 at 02:28 PM CEST #

I once tried working with H2 and HSQLDB for unit testing JPA 1.0 code. I create a new numbered .sql script for every commit that changes database DDL so when I check-out a particular revision of code I can build the database as it was at that time. For my tests I would run these scripts and get errors in H2 because it wasn't compatible with all of SQL or possibly Postgres specific things. In the end I decided to have the tests run directly against a postgres server that is dedicated to testing.

I've always been weary of letting the O/R mapper figure out the difference between a database and the model objects, and letting it update the DDL. Maybe I should consider looking at fully describing the schema using JPA annotations and giving it a try so the JPA provider can run on production databases and JavaDB, H2, etc. One issue I foresee is persistence.xml needing to be updated when I change database vendors (production/test) unless it can detect automatically. I think TopLink Essentials detects automatically, I'm not sure about Hibernate.

Posted by Ryan de Laplante on July 16, 2009 at 04:54 PM CEST #

regarding DB2. Apache Derby (-> JavaDB) was donated by IBM to the ASF, so I guess the DB2 stuff is not a big surprise.

Posted by Matthias Wessendorf on July 22, 2009 at 02:00 PM CEST #

@Matthias,

but the quality of the DB 2 support really surprised me. Even some optimizer hints are supported.
Beyond that - Java-Stored procedures are interesting as well,

thanks!,

adam

Posted by Adam Bien on July 22, 2009 at 02:13 PM CEST #

because of different bugs fixed for the in-memory mode you should also look on the upcomming 10.5.2 Release

http://people.apache.org/~kmarsden/derby10.5.2.0.794445/

n.b.: derby has more interesting, but very unknown features (like build in cluster support, xml-datatype and virtual tables) .
Described in my german article in the current database pro magazin 4/2009

Posted by pif on July 27, 2009 at 07:07 PM CEST #

@PIF,

yes, especially the cluster support is interesting.

thanks for the comment!,

adam

Posted by Adam Bien on July 27, 2009 at 08:00 PM CEST #

Hi Adam,

What did you have to do to get your netbeans project to locate the location of your "test" persistence.xml file?

Currently, if I call Persistence from any unit test, I get a failure from toplink saying that there are no persistence provider named test.

Posted by Patrick Julien on October 27, 2009 at 04:51 AM CET #

Acolyte framework is another way of doing so: manage the JDBC connection by yourself during test, to be sure which resultset/update count it returns for each update/query statement. https://github.com/cchantep/acolyte

Posted by applicius on March 01, 2014 at 12:19 PM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
...the last 150 posts
...the last 10 comments
License