Programming
28 May 2012 0 Comments

Adding JPA Support to a Maven/Eclipse/JSF2 Project

Introduction

the Java Persistence API (JPA) allows for easy managing of relational data in Java applications. It is a replacement of the much criticized EJB 2.0 and EJB 2.1 entity beans. In this post we show how to add JPA support to an existing Maven/Eclipse/JSF2 project with Java EE 6.

With JPA you can do create an entity that is backed by a table in the database. For example you can create a persisted entity (which is just a POJO with some annotations):

Name.java

import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.Column;
 
@Entity
@Table(name="CUSTOMER_INFORMATION")
public class Customer {
    private String name;
 
    @Id
    @Column(name="FULL_NAME")
    public int getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name= name;
    }
}

And a client class that fetches all customer names with and prints them:
Client.java

import javax.persistence.Persistence;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityManager;
 
public class Client {
 
    public void printNames() {
        System.out.println("The customer names are:");
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("examplePersistenceUnit");
        EntityManager em = emf.createEntityManager();
 
        final List<Customer> customers = em.createQuery("select c from Customer c")
                .getResultList();
        for (Customer c: customers) {
            System.out.println(c.getName());
        }
    }
}

Example output:

The customer names are:
John
Jack
Dave

Add JPA Dependencies to pom.xml

JPA is part of the Java EE specification, more specifically the javax.persistence.* package. Let’s think about which dependencies we need to add to our pom.xml to make JPA work.

  1. Application servers such as Glassfish and JBoss are fully Java EE compliant, and will provide an implementation of the javax.persistence.* classes at runtime. You can just deploy classes that using javax.persistence.Persist to Glassfish, without having to include any JAR files. So no need to modify the pom.xml for that situation.
  2. Compiling Java EE code requires that the Java EE API is available on the classpath. We solved this by adding the following dependency:
    >
        >javax>
        >javaee-api>
        >6.0>
        >provided>
    >

    Note that this artifact only provides the Java EE API, not the method bodies. For compilation only this works fine, but you can’t run the code locally with it! I’m not sure why the Java API does not provide implementations, most likely it is to keep the JAR size down and be implementation-independent. But it sure is a headache for many developers.

  3. When unit testing the application, e.g. with JUnit, it needs to run locally instead of in an application server such as Glassfish. To run outside of an application server we need provide implementations for the javax.persistence.* classes ourselves. Glassfish uses EclipseLink for its JPA implementation, so let’s change our test-time dependencies to include EclipseLink.

    First, add the EclipseLink repository to the pom:

      >
        >
            >EclipseLink Repo>
            >http://download.eclipse.org/rt/eclipselink/maven.repo>
            >
                >true>
            >
        >
      >

    Next we include the EclipseLink libraries with the ‘test’ scope above the Java EE API. This way, the javax.persistence classes will be resolved to the EclipseLink artifact instead of the javaee-api artifact. We also need a database driver, in this case PostgreSQL. Together it looks like this:

        >
          >org.eclipse.persistence>
          >eclipselink>
          >2.0.0>
          >test>
        >
        >
          >org.eclipse.persistence>
          >javax.persistence>
          >2.0.0>
          >test>
        >
        >
          >javax>
          >javaee-api>
          >6.0>
          >provided>
        >

Add JPA Facet to Eclipse Project

Eclipse provides excellent JPA support out of the box, but it requires some work to use it with a M2Eclipse/Maven project. Here is how I did it:

  1. Re-open the Project Properties go to Project Facets and check ‘JPA’, version 2.0.
  2. In the bottom, click on ‘Further configuration available…’.
  3. For JPA Implementation choose ‘Disable Library Configuration’, since this is handled by Maven.
  4. Set the connection details under ‘Connection’, and click OK. This will create a META-INF directory under src/main/java.
  5. Drag the META-INF directory from src/main/java to src/main/resources. Make sure src/main/resources is on the Build Path (rightclick, Build Path, Add to Build Path). You will get an error message and the ‘JPA Content’ node will stop working.
  6. Now go into the Project Properties again, and uncheck ‘JPA’, apply the change, and re-enable JPA. Now it should correctly use the persistence.xml file in src/main/resources/META-INF.

Now when building a WAR file, the persistence.xml file will be copied to /WEB-INF/classes/META-INF/persistence.xml, which is one of the valid locations.

Configure a Persistence Unit

Before you can use all the sweet JPA features, you need to create a persistence unit and assign a data source to it (a database connection). Some good sources to learn about the configuration of JPA are:

You may also be interested in another post here: Using @DataSourceDefinition in Java EE 6 With Postgresql