Unit test JPA Entities with in-memory Derby/JavaDB
About two years ago I blogged about using HSQLDB to unit test JPA entities. This year, Apache released a Derby version allowing you to use an in memory backend. As I use Derby in software I write, being able to run unit tests on the very same SGBD but in memory is a real gift.
For reference, here is a link to my previous post titled Unit test JPA Entities with in-memory database. What follows is just the very same method applied to Derby.
Dependencies
Here are the dependencies I added to my project with the “test” scope :
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.2.GA</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.5.3.0</version>
<scope>test</scope>
</dependency>
Persistence Unit
Here the interesting snippet of my META-INF/persistence.xml file :
<persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>myapp.model.entities.Group</class>
<class>myapp.model.entities.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.url" value="jdbc:derby:memory:unit-testing-jpa"/>
<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.connection.username" value=""/>
<property name="hibernate.connection.password" value=""/>
</properties>
</persistence-unit>
The unit test
Here is a simple complete test case :
public class PersistenceUnitTest extends TestCase {
private static Logger logger = Logger.getLogger(PersistenceUnitTest.class.getName());
private EntityManagerFactory emFactory;
private EntityManager em;
public PersistenceUnitTest(String testName) {
super(testName);
}
@Override
protected void setUp() throws Exception {
super.setUp();
try {
logger.info("Starting in-memory database for unit tests");
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
DriverManager.getConnection("jdbc:derby:memory:unit-testing-jpa;create=true").close();
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception during database startup.");
}
try {
logger.info("Building JPA EntityManager for unit tests");
emFactory = Persistence.createEntityManagerFactory("testPU");
em = emFactory.createEntityManager();
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception during JPA EntityManager instanciation.");
}
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
logger.info("Shuting down Hibernate JPA layer.");
if (em != null) {
em.close();
}
if (emFactory != null) {
emFactory.close();
}
logger.info("Stopping in-memory database.");
try {
DriverManager.getConnection("jdbc:derby:memory:unit-testing-jpa;shutdown=true").close();
} catch (SQLNonTransientConnectionException ex) {
if (ex.getErrorCode() != 45000) {
throw ex;
}
// Shutdown success
}
VFMemoryStorageFactory.purgeDatabase(new File("unit-testing-jpa").getCanonicalPath());
}
public void testPersistence() {
try {
em.getTransaction().begin();
User u = new User();
u.setEmail("eskatos@yopmail.com");
u.setFirstName("eskatos");
u.setLastName("YOP");
u.setOrganisation("Tagada");
em.persist(u);
assertTrue(em.contains(u));
Group g = new Group();
g1.addUser(u);
em.persist(g);
assertTrue(em.contains(g));
g.removeUser(u);
em.remove(u);
em.merge(g);
assertFalse(em.contains(u));
em.getTransaction().commit();
} catch (Exception ex) {
em.getTransaction().rollback();
ex.printStackTrace();
fail("Exception during testPersistence");
}
}
}
Et voila, now with Derby :) !

[...] UPDATE: now that Apache Derby provide an in memory backend, I implemented the very same thing with it in a new post : Unit test JPA Entities with in-memory Derby/JavaDB [...]
Unit test JPA Entities with in-memory database « eskatos's thoughts
October 27, 2009 at 12:34 pm
Thanks for the information, eskatos.
Great to see the in-memory back end being used :)
I just want to point out that the way to delete Derby / Java DB in-memory databases (and possibly other types of databases) will change in the next feature release. The current mechanism I’m looking into is using a connection URL property, like “jdbc:derby:memory;mydb;delete=true[;user=...;password=...]“.
If anyone has feedback on the current implementation or wishes for future features, feel free to share it with the community on the Apache Derby user’s mailing list. The in-memory database back end in Derby 10.5 is considered experimental, so this is the time to raise your opinion if you want to see major compatibility breaking changes!
Regards,
Kristian Waagan
October 27, 2009 at 6:17 pm
Great post! I have a question, though. I am planning to use it for unit testing seam ejb using maven. Where do I put META-INF/persistence.xml file? Under \test\resources directory? Thank you in advance.
Brian Ko
January 16, 2010 at 2:15 am
@Brian: yes, in src/test/resources/META-INF
eskatos
January 16, 2010 at 8:14 pm
Hi,
I did exactly the same with Derby for inmemory testing and encapsulated it into a framework. The framework allows inmemory testing as well as connecting to a third-party framework.
Have a look at http://utils.wamblee.org/test/enterprise/index.html, and in particular at http://utils.wamblee.org/test/enterprise/apidocs/org/wamblee/test/persistence/package-summary.html
I am developing this as open source and it is available on the central maven repo.
Cheers
Erik
Erik Brakkee
July 19, 2010 at 12:40 am
correction: “connection to a third-party framework” should be “connecting to an external database”.
Erik Brakkee
July 19, 2010 at 12:41 am
[...] Configuración de JPA para usar Hibernate [...]
Uso de JPA, Hibernate y Derby « Ruben ChT's Blog
May 19, 2011 at 11:05 am