Monday, February 25, 2008

Testing EclipseLink JPA applications in JavaSE

I spend part of my work days writing examples and helping users debug issues. I spend the majority of this time using JPA with our TopLink and now EclipseLink's advanced features.

One little piece of code I always find myself looking for is a way to take a JPA persistence unit configuration and use it in JavaSE without changing it. The idea is that my persistence unit which should run in the container should also be testable easily outside.

In the past I posted some examples of using XML to accomplish this but the following is the Java code that I use in my JavaSE examples and unit tests without going down the road of a separate persistence unit definition in XML for both worlds.


import static org.eclipse.persistence.jpa.config.PersistenceUnitProperties.*;

...

Map properties = new HashMap();

// Ensure RESOURCE_LOCAL transactions is used.
properties.put(TRANSACTION_TYPE,
PersistenceUnitTransactionType.RESOURCE_LOCAL.name());

// Configure the internal EclipseLink connection pool
properties.put(JDBC_DRIVER, "oracle.jdbc.OracleDriver");
properties.put(JDBC_URL, "jdbc:oracle:thin:@localhost:1521:ORCL");
properties.put(JDBC_USER, "user-name");
properties.put(JDBC_PASSWORD, "password");
properties.put(JDBC_READ_CONNECTIONS_MIN, "1");
properties.put(JDBC_WRITE_CONNECTIONS_MIN, "1");

// Configure logging. FINE ensures all SQL is shown
properties.put(LOGGING_LEVEL, "FINE");

// Ensure that no server-platform is configured
properties.put(TARGET_SERVER, TargetServer.None);


I can then create my EntityManagerFactory using:


Persistence.createEntityManagerFactory("unit-name", properties);


The only remaining struggle I have is specifying which classes are my entities. The simplest way is to explicitly reference them in the persistence.xml or an associated orm.xml file. If they are listed explicitly then I do not need to worry about the automatic discovery.

EclipseLink does support automatic discovery of entity classes in JavaSE but you need to enable its usage using:

<persistence-unit name="unit-name">
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>

Hopefully having these snippets of code and XML handy will help some of you out and now I can easily find them wherever I am working.

Doug