Close

JPA Kickstart Example

[Last Updated: Mar 3, 2017]

Followings are the key concepts of JPA specifications (JSR 338):

  1. JPA is a standard way to access database, to persist Java Objects to database, to retrieve Java Objects from database, taking care of transaction management and to perform other persistence related tasks.

  2. A developer works with javax.persistence package. EntityManager class is the entry point to use this API.

  3. It provides database neutral way to talk to the underlying database via Java Persistence Query Language (JPQL). The query is still string based. We execute JPQL queries using method EntityManager.createQuery(String) and overloaded methods EntityManager.createNamedQuery().

  4. It provides a database neutral and type safe way to talk to the underlying database via Criteria API, defined in javax.persistence.criteria package. Here we work with Java Objects rather than string based queries. The typical entry point to start with the criteria API is EntityManager.getCriteriaBuilder().

  5. It provides Object/relational annotations (like @Entity, @Id etc). We use these annotations on our entity objects, so that underlying implementation of JPA will know how to perform ORM (mapping Java Objects/fields to database tables/columns).


Example

In this standalone example we are going to use H2 database and EclipseLink as a JPA implementation which is also the JPA reference implementation.


Maven dependencies:

<project>
 .....
<dependencies>
 <dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <version>1.4.193</version>
 </dependency>

 <dependency>
  <groupId>org.eclipse.persistence</groupId>
  <artifactId>eclipselink</artifactId>
  <version>2.6.4</version>
 </dependency>

 <dependency>
  <groupId>org.eclipse.persistence</groupId>
  <artifactId>javax.persistence</artifactId>
  <version>2.1.1</version>
 </dependency>
</dependencies>
 ....
</project>

Entity object

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class MyObject {
    @Id
    @GeneratedValue
    private long objId;
    private String str;

   //getters, setters and toString
}

persistence.xml

This configuration file should be under META-INF folder. It defines a named <persistence-unit> with information like database connection string, the ORM provider etc.

<persistence ...>
 <persistence-unit name="testPersistenceUnit" transaction-type="RESOURCE_LOCAL">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <exclude-unlisted-classes>false</exclude-unlisted-classes>
  <properties>
   <property name="javax.persistence.schema-generation.database.action" value="create"/>
   <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"/>
  </properties>
 </persistence-unit>
</persistence>

In above url string, we are specifying H2 should run in memory mode. Also javax.persistence.schema-generation.database.action=create will auto-create the tables for our entity objects.

Also note that in an application server environment, we may want to specify <jta-data-source> instead of connection string property.

Complete reference of persistence.xml can be found in JSR-338 pdf.


Main method

We are going to access same named persistence-unit defined in the persistence.xml above.

import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import java.util.Arrays;
import java.util.List;

public class JPAKickStartExample {

    public static void main (String[] args) {

        EntityManagerFactory emf =
                            Persistence.createEntityManagerFactory("testPersistenceUnit");
        EntityManager entityManager = emf.createEntityManager();
        entityManager.getTransaction().begin();

        MyObject myObject = new MyObject();
        myObject.setStr("one");
        entityManager.persist(myObject);

        myObject = new MyObject();
        myObject.setStr("two");
        entityManager.persist(myObject);

        entityManager.getTransaction().commit();

        findObjectById(entityManager);
        queryWithJPQL(entityManager);
        typedQueryWithJPQL(entityManager);
        criteriaQuery(entityManager);
        queryNative(entityManager);
    }

    private static void findObjectById (EntityManager entityManager) {
        System.out.println("----\nfinding object by id");
        MyObject o = entityManager.find(MyObject.class, 2L);
        System.out.println(o);
    }

    private static void queryWithJPQL (EntityManager entityManager) {
        System.out.println("----\nQuerying using JPQL");
        Query query = entityManager.createQuery("select t from MyObject t");
        List resultList1 = query.getResultList();
        System.out.println(resultList1);
    }

    private static void typedQueryWithJPQL (EntityManager entityManager) {
        System.out.println("----\nTyped Querying using JPQL");
        TypedQuery<MyObject> q =
                            entityManager.createQuery("select t from MyObject t"
                                                , MyObject.class);
        System.out.println(q.getResultList());
    }

    private static void queryNative (EntityManager entityManager) {
        System.out.println("----\nnative query");
        Query nativeQuery = entityManager.createNativeQuery("select * from MyObject");
        List resultList = nativeQuery.getResultList();
        for (Object o : resultList) {
            if (o.getClass().isArray()) {
                Object oa[] = (Object[]) o;
                System.out.println(Arrays.asList(oa));
            } else {
                System.out.println(o);
            }
        }
    }


    private static void criteriaQuery (EntityManager entityManager) {
        System.out.println("----\ncriteria query");
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Object> query = cb.createQuery();
        CriteriaQuery<Object> select = query.select(query.from(MyObject.class));

        TypedQuery<Object> typedQuery = entityManager.createQuery(select);
        System.out.println(typedQuery.getResultList());
    }
}

Output

[EL Info]: 2016-12-06 21:45:18.242--ServerSession(2116908859)--EclipseLink, version: Eclipse Persistence Services - 2.6.4.v20160829-44060b6
[EL Info]: connection: 2016-12-06 21:45:18.403--ServerSession(2116908859)--/file:/D:/LogicBig/example-projects/jpa/jpa-kickstart-example/target/classes/_testPersistenceUnit login successful
----
finding object by id
MyObject{objId=2, str='two'}
----
Querying using JPQL
[MyObject{objId=1, str='one'}, MyObject{objId=2, str='two'}]
----
Typed Querying using JPQL
[MyObject{objId=1, str='one'}, MyObject{objId=2, str='two'}]
----
criteria query
[MyObject{objId=1, str='one'}, MyObject{objId=2, str='two'}]
----
native query
[1, one]
[2, two]

Example project

Dependencies and Technologies Used:

  • H2 Database Engine 1.4.193: H2 Database Engine.
  • EclipseLink (non-OSGi) 2.6.4: EclipseLink build based upon Git transaction 44060b6.
    Related JPA version: org.eclipse.persistence:javax.persistence version 2.1.1
  • Javax Persistence 2.1.1: javax.persistence build based upon git transaction 40384f5.
  • JDK 1.8
  • Maven 3.3.9

Jpa Kickstart Select All Download
  • jpa-kickstart-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • JPAKickStartExample.java
          • resources
            • META-INF

    See Also