Tag Archives: jpa

Enhance OpenJPA entities with Gradle


OpenJPA has a Maven plugin but doesn’t provide a gradle plugin (yet?) but build-time enhancing is still a nice solution to ensure your entities will behave correctly whatever deployment you choose (in a plain TomEE the built-in javaagent does the work well but in embedded tests it is not guaranteed).

Is that a reason to abandon Gradle? Maybe not yet ;).

Continue reading

JPA + Java8 Stream = paginated findAll()


For batch tasks it is quite common to need to browse a full table. Depending the table it can be done in memory without thinking much or it can be too big and needs pagination.

A common solution was to use a kind of PageResult object which was representing the current page and its index and let the client/caller iterating over PageResults.

With java 8 streams the API can be more concise and efficient.

Continue reading

Simple Java 8 JPA JUnit rule


When you have JPA specific logic or a complex object graph, you surely want to test JPA without worrying of testing your whole application (i.e you just need a plain entity manager and no container).

To do so, you can of course create your entity manager factory, then you create an entity manager and play with it. But it can be nice, in particular with Java 8, to write a small JUnit rule to simply this kind of testing.

This rule would take in charge:

– a default configuration
– the ability to configure the persistent unit
– the ability to run a task in a transaction
– the ability to use the entitymanager without worrying of its creation

Create a JUnit rule

To create a JUnit rule you need to implement `org.junit.rules.TestRule`.

public class OpenJPARule implements TestRule {
  @Override
  public Statement apply(Statement base, Description description) {
      return new Statement() {
        @Override
        public void evaluate() throws Throwable {
            base.evaluate();
        }
    };
}

This implementation does nothing, it simply delegates to the original execution. Yet, we now see that we can wrap `base.evaluate()` in a try/finally block and add some code before and after the execution.

That’s what we’ll do.

Instead of using standard `Persistence` factory class to create the `EntityManagedFactory`, we’ll use OpenJPA on (`org.apache.openjpa.persistence.OpenJPAPersistence`) because it doesn’t need a persistence.xml to exist.

Our implementation will then look like:

OpenJPAEntityManagerFactory emf = OpenJPAPersistence.createEntityManagerFactory("test", null, config);
OpenJPAEntityManager em = emf.createEntityManager();
try {
    base.evaluate();
} finally {
    em.close();
    emf.close();
}

This is great but we can’t do much with this `EntityManager` while it is not accessible to the application.

To keep the ability to run tests in parallel, we’ll store it in a thread local in the rule:

package com.github.rmannibucau.openjpa.java8.junit;

import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.hsqldb.jdbcDriver;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import static java.util.Arrays.asList;

public class OpenJPARule implements TestRule {
    private final ThreadLocal<EntityManager> em = new ThreadLocal<>();

    @Override
    public Statement apply(Statement base, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                OpenJPAEntityManagerFactory emf = OpenJPAPersistence.createEntityManagerFactory("test", null, config);
                OpenJPAEntityManager em = emf.createEntityManager();
                OpenJPARule.this.em.set(em);
                try {
                    base.evaluate();
                } finally {
                    em.close();
                    emf.close();
                    OpenJPARule.this.em.remove();
                }
            }
        };
    }
}

By making the thread local accessible, we’ll be able to use it in the application. But before we’ll need
an entity manager which can be created. That’s to say we need some configuration.

For the testing purpose we’ll use hsqldb as testing database (h2 would be perfect as well) and we’ll use a default
configuration already wiring a datasource, forcing to create the schema and supporting unenhanced classes.

Note: this last point is used for small tests but it is not recommanded to count on it in a real application (with relationships).

Here is our default configuration:

Map config = new HashMap() {{
    put("javax.persistence.jdbc.driver", jdbcDriver.class.getName());
    put("javax.persistence.jdbc.url", "jdbc:hsqldb:mem:test");
    put("javax.persistence.jdbc.user", "sa");
    put("javax.persistence.jdbc.password", "");

    put("openjpa.RuntimeUnenhancedClasses", "supported");

    put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");

    put("openjpa.InitializeEagerly", "true");
}};

We’ll store this configuration in our rule, allowing us to customize it through a configure method. We’ll also add a particular
method that enables to specify which types are taken into account (entities). This is done by setting `openjpa.MetaDataFactory`
property giving a value to `types` key:

public class OpenJPARule implements TestRule {
    private final ThreadLocal<EntityManager> em = new ThreadLocal<>();
    private final Map config = new HashMap() {{
        put("javax.persistence.jdbc.driver", jdbcDriver.class.getName());
        put("javax.persistence.jdbc.url", "jdbc:hsqldb:mem:test");
        put("javax.persistence.jdbc.user", "sa");
        put("javax.persistence.jdbc.password", "");

        put("openjpa.RuntimeUnenhancedClasses", "supported");

        put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");

        put("openjpa.InitializeEagerly", "true");
    }};

    public OpenJPARule configure(final String key, final String value) {
        config.put(key, value);
        return this;
    }

    public OpenJPARule types(final Class<?>... classes) {
        configure("openjpa.MetaDataFactory", "types=" + asList(classes).stream().map(Class::getName).collect(Collectors.joining(",")));
        return this;
    }

    @Override
    public Statement apply(Statement base, Description description) {
      // ...
    }
}

Now, to miss a way to use the rule and `EntityManager`, we’ll provide two methods:

– run: execute a task getting the entity manager as parameter. `java.util.function.Consumer` is a perfect parameter for that
– transaction: execute a task in a transaction. Here, returning some values (persisted entity?) is nice, so we’ll use `java.util.function.Function` as parameter

Finally these methods will look like:

public void run(Consumer<EntityManager> task) {
    task.accept(em.get());
}

public <T> T transaction(Function<EntityManager, T> task) {
    EntityManager entityManager = em.get();
    EntityTransaction tx = entityManager.getTransaction();
    tx.begin();
    boolean cancelled = false;
    try {
        return task.apply(entityManager);
    } catch (RuntimeException e) {
        cancelled = true;
        tx.rollback();
        throw e;
    } finally {
        if (!cancelled) {
            tx.commit();
        }
    }
}

What is nice in using `Function` and `Consumer` is that it is lambda friendly.

Use the OpenJPA JUnit rule

Now we have all the code, we can use our rule in test class:

public class JPATest {
    @Rule
    public final OpenJPARule $ = new OpenJPARule()
            .types(DatedEntity.class)
            .configure("openjpa.Log", "SQL=TRACE");

    @Test
    public void doPersist() {
        final AnEntity de = new AnEntity();
        $.transaction((em) -> {
            em.persist(de);
            return de;
        });
        $.run(EntityManager::clear);
    }
}

TomEE and finer RESOURCE_LOCAL persistence unit configuration


The issue with RESOURCE_LOCAL units is that it is used a bit differently if you are in a EE container or not. Basically in a container the spec mandates the unit type to be JTA is you don’t specify any datasource (jta and non jta one)…even if you set RESOURCE_LOCAL.

Issue is: in standalone mode you never do it so if you import a standalone app then it is broken.

That’s why TomEE added two configurable properties (system properties or unit properties).

Continue reading

JPA entities scanning in TomEE


JPA offers the ability to discover entities scanning the application classes instead of asking you to define all entities in the persistence unit. It is the effect of ‘exclude-unlisted-classes’ parameter.

For a simple application with a single persistence unit it is pretty nice but it means the container will scan your app for CDI, JSF, EJB…stuffs (in TomEE we already unified those parts – one of the reason why you shouldn’t use a plain old Tomcat if you use more than one of these technologies) then re-scan it for JPA (it is delegated to the JPA provider).

For big apps it can be a little pain to write/work on integration tests and moreover it uses more memory (scanning is not shared).

Continue reading