Archive for the ‘JPA’ Category

In my last article I showed two different ways to read/write persistent entity state – field and property. When field access mode is used, JPA directly reads the state values from the fields of an entity using reflection. It directly translates the field names into database column names if we do not specify the column names explicitly.  In case of property access mode, the getter/setter methods are used to read/write the state values. In this case we annotate the getter methods of the entity states instead of the fields using the same annotations. If we do not explicitly specify the database column names then they are determined following the JavaBean convention, that is by removing the “get” portion from the getter method name and converting the first letter of the rest of the method name to lowercase character.

We can specify which access mode to use for an entity by using the @Access annotation in the entity class declaration. This annotation takes an argument of type AccessType (defined in the javax.persistence package) enum, which has two different values corresponding to two different access modes – FIELD and PROPERTY. As an example, we can specify property access mode for the Address entity in the following way –

@Entity
@Table(name = "tbl_address")
@Access(AccessType.PROPERTY)
public class Address {
  private Integer id;
  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;
  private String transientColumn;

  @Id
  @GeneratedValue
  @Column(name = "address_id")
  public Integer getId() {
    return id;
  }

  public Address setId(Integer id) {
    this.id = id;
    return this;
  }

  public String getStreet() {
    return street;
  }

  public Address setStreet(String street) {
    this.street = street;
    return this;
  }

  public String getCity() {
    return city;
  }

  public Address setCity(String city) {
    this.city = city;
    return this;
  }

  public String getProvince() {
    return province;
  }

  public Address setProvince(String province) {
    this.province = province;
    return this;
  }

  public String getCountry() {
    return country;
  }

  public Address setCountry(String country) {
    this.country = country;
    return this;
  }

  public String getPostcode() {
    return postcode;
  }

  public Address setPostcode(String postcode) {
    this.postcode = postcode;
    return this;
  }
}

Couple of points to note about the above example –

  1. As discussed before, we are now annotating the getter method of the entity id with the @Id@GeneratedValue and @Column annotations.
  2. Since now column names will be determined by parsing the getter methods, we do not need to mark the transientColumn field with the @Transient annotation anymore. However if Address entity had any other method whose name started with “get”, then we needed to apply @Transient on it.

If an entity has no explicit access mode information, just like our Address entity that we created in the first part of this series, then JPA assumes a default access mode. This assumption is not made at random. Instead, JPA first tries to figure out the location of the @Id annotation. If the @Id annotation is used on a field, then field access mode is assumed. If the @Id annotation is used on a getter method, then property access mode is assumed. So even if we remove the @Access annotation from the Address entity in the above example the mapping will still be valid and JPA will assume property access mode –

@Entity
@Table(name = "tbl_address")
public class Address {
  private Integer id;
  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;
  private String transientColumn;

  @Id
  @GeneratedValue
  @Column(name = "address_id")
  public Integer getId() {
    return id;
  }

  // Rest of the class........
  

Some important points to remember about the access modes –

  1. You should never declare a field as public if you use field access mode. All fields of the entity should have either private (best!), protected or default access type. The reason behind this is that declaring the fields as public will allow any unprotected class to directly access the entity states which could defeat the provider implementation easily. For example, suppose that you have an entity whose fields are all public. Now if this entity is a managed entity (which means it has been saved into the database) and any other class changes the value of its id, and then you try to save the changes back to the database, you may face unpredictable behaviors (I will try to elaborate on this topic in a future article). Even the entity class itself should only manipulate the fields directly during initialization (i.e., inside the constructors).
  2. In case of property access mode, if we apply the annotations on the setter methods rather than on the getter methods, then they will simply be ignored.

It’s also possible to mix both of these access types. Suppose that you want to use field access mode for all but one state of an entity, and for that one remaining state you would like to use property access mode because you want to perform some conversion before writing/after reading the state value to and from the database. You can do this easily by following the steps below –

  1. Mark the entity with the @Access annotation and specify AccessType.FIELD as the access mode for all the fields.
  2. Mark the field for which you do not like to use the field access mode with the @Transient annotation.
  3. Mark the getter method of the property with the @Access annotation and specify AccessType.PROPERTY as the access mode.

The following example demonstrates this approach as the postcode has been changed to use property access mode –

@Entity
@Table(name = "tbl_address")
@Access(AccessType.FIELD)
public class Address {
  @Id
  @GeneratedValue
  @Column(name = "address_id")
  private Integer id;

  private String street;
  private String city;
  private String province;
  private String country;
 
  /**
    * postcode is now marked as Transient
    */
  @Transient
  private String postcode;
 
  @Transient
  private String transientColumn;

  public Integer getId() {
    return id;
  }

  public Address setId(Integer id) {
    this.id = id;
    return this;
  }

  public String getStreet() {
    return street;
  }

  public Address setStreet(String street) {
    this.street = street;
    return this;
  }

  public String getCity() {
    return city;
  }

  public Address setCity(String city) {
    this.city = city;
    return this;
  }

  public String getProvince() {
    return province;
  }

  public Address setProvince(String province) {
    this.province = province;
    return this;
  }

  public String getCountry() {
    return country;
  }

  public Address setCountry(String country) {
    this.country = country;
    return this;
  }

  /**
    * We are now using property access mode for reading/writing
    * postcode
    */
  @Access(AccessType.PROPERTY)
  public String getPostcode() {
    return postcode;
  }

  public Address setPostcode(String postcode) {
    this.postcode = postcode;
    return this;
  }
}

The important thing to note here is that if we do not annotate the class with the @Access annotation to explicitly specify the field access mode as the default one, and we annotate both the fields and the getter methods, then the resultant behavior of the mapping will be undefined. Which means the outcome will totally depend on the persistence provider i.e., one provider might choose to use the field access mode as default, one might use property access mode, or one might decide to throw an exception!

That’s it for today. If you find any problems/have any questions, please do not hesitate to comment!

Until next time.

Resources

  1. Pro JPA 2 by Mike Keith, Merrick Schincariol
  2. Java Persistence WikiBook

In my last post I showed a simple way of persisting an entity. I explained the default approach that JPA uses to determine the default table for an entity. Let’s assume that we want to override this default name. We may like to do so because the data model has been designed and fixed before and the table names do not match with our class names (I have seen people to create tables with “tbl_” prefix, for example). So how should we override the default table names to match the existing data model?

Turns out, it’s pretty simple. If we need to override the default table names assumed by JPA, then there are a couple of ways to do it –

  1. We can use the name attribute of the @Entity annotation to provide an explicit entity name to match with the database table name. For our example we could have used @Entity(name = “tbl_address”) in our Address class if our table name was tbl_address.
  2. We can use a @Table (defined in the javax.persistence package) annotation just below the @Entity annotation and use its name attribute to specify the table name explicitly –
@Entity
@Table(name = "tbl_address")
public class Address {
  // Rest of the class
}

From these two approaches the @Table annotation provides more options to customize the mapping. For example, some databases like PostgreSQL have a concept of schemas, using which you can further categorize/group your tables. Because of this feature you can create two tables with the same name in a single database (although they will belong to two different schemas). To access these tables you then add the schema name as the table prefix in your query. So if a PostgreSQL database has two different schemas named public (which is sort of like default schema for a PostgreSQL database) and document, and both of these schemas contain tables named document_collection, then both of these two queries are perfectly valid –

-- fetch from the table under public schema
SELECT *
FROM   public.document_collection;

-- fetch from the table under document schema
SELECT *
FROM   document.document_collection;

In order to map an entity to the document_collection table in the document schema, you will then use the @Table annotation with its schema attribute set to document

@Entity
@Table(name="document_collection", schema="document")
public class DocumentCollection {
  // rest of the class
}

When specified this way, the schema name will be added as a prefix to the table name when the JPA goes to the database to access the table, just like we did in our queries.

What if rather than specifying the schema name in the @Table annotation you append the schema name in the table name itself, like this –

@Entity
@Table(name = "document.document_collection")
public class DocumentCollection {
  // rest of the class
}

Inlining the schema name with the table name this way is not guaranteed to work across all JPA implementations because support for this is not specified in the JPA specification (non-standard). So it’s better if you do not make a habit of doing this even if your persistence provider supports it.

Let’s turn our attention to the columns next. In order to determine the default columns, JPA does something similar to the following –

  1. At first it checks to see if any explicit column mapping information is given. If no column mapping information is found, it tries to guess the default values for columns.
  2. To determine the default values, JPA needs to know the access type of the entity states i.e., the way to read/write the states of the entity. In JPA two different access types are possible – field and property. For our example we have used the field access (actually JPA assumed this from the location/placement of the @Id annotation,  but more on this later). If you use this access type then states will be written/read directly from the entity fields using the Reflection API.
  3. After the access type is known, JPA then tries to determine the column names. For field access type JPA directly treats the field name as the column names, which means if an entity has a field named status then it will be mapped to a column named status.

At this point it should be clear to us how the states of the Address entities got saved into the corresponding columns. Each of the fields of the Address entity has an equivalent column in the database table tbl_address, so JPA directly saved them into their corresponding columns. The id field was saved into the id column, city field into the city column and so on.

OK then, let’s move on to overriding column names. As far as I know there is only one way (if you happen to know of any other way please comment in!) to override the default column names for entity states, which is by using the @Column (defined in the javax.persistence package) annotation. So if the id column of the tbl_address table is renamed to be address_id then we could either change our field name to address_id, or we could use the @Column annotation with its name attribute set to address_id

@Entity
@Table(name = "tbl_address")
public class Address {
  @Id
  @GeneratedValue
  @Column(name = "address_id")
  private Integer id;

  // Rest of the class
}

You can see that for all the above cases the default approaches that JPA uses are quite sensible, and most of the cases you will be happy with it. However, changing the default values are also very easy and can be done very quickly.

What if we have a field in the Address entity that we do not wish to save in the database? Suppose that the Address entity has a column named transientColumn which does not have any corresponding default column in the database table –

@Entity
@Table(name = "tbl_address")
public class Address {
  @Id
  @GeneratedValue
  @Column(name = "address_id")
  private Integer id;

  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;
  private String transientColumn;

  // Rest of the class
}

If you compile your code with the above change then you will get an exception which looks something like below –

Exception in thread “main” java.lang.ExceptionInInitializerError
at com.keertimaan.javasamples.jpaexample.Main.main(Main.java:33)
Caused by: javax.persistence.PersistenceException: Unable to build entity manager factory
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:83)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:54)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at com.keertimaan.javasamples.jpaexample.persistenceutil.PersistenceManager.<init>(PersistenceManager.java:31)
at com.keertimaan.javasamples.jpaexample.persistenceutil.PersistenceManager.<clinit>(PersistenceManager.java:26)
… 1 more
Caused by: org.hibernate.HibernateException: Missing column: transientColumn in jpa_example.tbl_address
at org.hibernate.mapping.Table.validateColumns(Table.java:365)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1336)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:525)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:75)
… 6 more

The exception is saying that the persistence provider could not find any column in the database whose name is transientColumn, and we did not do anything to make it clear to the persistence provider that we do not wish to save this field in the database. The persistence provider took it as any other fields in the entity which are mapped to database columns.

In order to fix this problem, we can do any of the following –

  1. We can annotate the transientColumn field with the @Transient (defined in javax.persistence package) annotation to let the persistence provider know that we do not wish to save this field, and it does not have any corresponding column in the table.
  2. We can use the transient keyword that Java has by default.

The difference between these two approaches that comes to my mind is that, if we use the transient keyword instead of the annotation, then if one of the Address entities gets serialized from one JVM to another then the transientColumn field will get reinitialized again (just like any other transient fields in Java). For the annotation, this will not happen and the transientColumn field will retain its value across the serialization. As a rule of thumb, I always use the annotation if I do not need to worry about serialization (and in most of the cases I don’t).

So using the annotation, we can fix the problem right away –

@Entity
@Table(name = "tbl_address")
public class Address {
  @Id
  @GeneratedValue
  @Column(name = "address_id")
  private Integer id;

  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;

  @Transient
  private String transientColumn;

  // Rest of the class
}

So that’s it for today folks. If you find any mistakes/have any input, please feel free to comment in!

Until next time.

In this article I will discuss about the entity mapping procedure in JPA. As for my examples I will use the same schema that I used in one of my previous articles.

In my two previous articles I explained how to set up JPA in a Java SE environment. I do not intend to write the setup procedure for a web application because most of the tutorials on the web do exactly that. So let’s skip over directly to object relational mapping, or entity mapping.

Wikipedia defines Object Relational Mapping as follows –

Object-relational mapping (ORM, O/RM, and O/R mapping) in computer science is a programming technique for converting data between incompatible type systems in object-oriented programming languages. This creates, in effect, a “virtual object database” that can be used from within the programming language. There are both free and commercial packages available that perform object-relational mapping, although some programmers opt to create their own ORM tools.

Typically, mapping is the process through which you provide necessary information about your database to your ORM tool. The tool then uses this information to read/write objects into the database. Usually you tell your ORM tool the table name to which an object of a certain type will be saved. You also provide column names to which an object’s properties will be mapped to. Relation between different object types also need to be specified. All of these seem to be a lot of tasks, but fortunately JPA follows what is known as “Convention over Configuration” approach, which means if you adopt to use the default values provided by JPA, you will have to configure very little parts of your applications.

In order to properly map a type in JPA, you will at a minimum need to do the following –

  1. Mark your class with the @Entity annotation. These classes are called entities.
  2. Mark one of the properties/getter methods of the class with the @Id annotation.

And that’s it. Your entities are ready to be saved into the database because JPA configures all other aspects of the mapping automatically. This also shows the productivity gain that you can enjoy by using JPA. You do not need to manually populate your objects each time you query the database, saving you from writing lots of boilerplate code.

Let’s see an example. Consider the following Address entity which I have mapped according to the above two rules –

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

@Entity
public class Address {
  @Id
  private Integer id;

  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;

  /**
   * @return the id
   */
  public Integer getId() {
    return id;
  }

  /**
   * @param id the id to set
   */
  public Address setId(Integer id) {
    this.id = id;
    return this;
  }

  /**
   * @return the street
   */
  public String getStreet() {
    return street;
  }

  /**
   * @param street the street to set
   */
  public Address setStreet(String street) {
    this.street = street;
    return this;
  }

  /**
   * @return the city
   */
  public String getCity() {
    return city;
  }

  /**
   * @param city the city to set
   */
  public Address setCity(String city) {
    this.city = city;
    return this;
  }

  /**
   * @return the province
   */
  public String getProvince() {
    return province;
  }

  /**
   * @param province the province to set
   */
  public Address setProvince(String province) {
    this.province = province;
    return this;
  }

  /**
   * @return the country
   */
  public String getCountry() {
    return country;
  }

  /**
   * @param country the country to set
   */
  public Address setCountry(String country) {
    this.country = country;
    return this;
  }

  /**
   * @return the postcode
   */
  public String getPostcode() {
    return postcode;
  }

  /**
   * @param postcode the postcode to set
   */
  public Address setPostcode(String postcode) {
    this.postcode = postcode;
    return this;
  }
}

Now based on your environment, you may or may not add this entity declaration in your persistence.xml file, which I have explained in my previous article.

Ok then, let’s save some object! The following code snippet does exactly that –

import com.keertimaan.javasamples.jpaexample.entity.Address;
import javax.persistence.EntityManager;
import com.keertimaan.javasamples.jpaexample.persistenceutil.PersistenceManager;

public class Main {
  public static void main(String[] args) {
    EntityManager em = PersistenceManager.INSTANCE.getEntityManager();

    Address address = new Address().setId(1)
        .setCity("Dhaka")
        .setCountry("Bangladesh")
        .setPostcode("1000")
        .setStreet("Poribagh");
    em.getTransaction()
        .begin();
    em.persist(address);
    em.getTransaction()
        .commit();
    System.out.println("addess is saved! It has id: " + address.getId());

    Address anotherAddress = new Address().setId(2)
        .setCity("Shinagawa-ku, Tokyo")
        .setCountry("Japan")
        .setPostcode("140-0002")
        .setStreet("Shinagawa Seaside Area");
    em.getTransaction()
        .begin();
    em.persist(anotherAddress);
    em.getTransaction()
        .commit();
    em.close();
    System.out.println("anotherAddress is saved! It has id: " + anotherAddress.getId());

    PersistenceManager.INSTANCE.close();
  }
}

Let’s take a step back at this point and think what we needed to do if we had used plain JDBC for persistence. We had to manually write the insert queries and map each of the attributes to the corresponding columns for both cases, which would have required a lot of code.

An important point to note about the example is the way I am setting the id of the entities. This approach will only work for short examples like this, but for real applications this is not good. You’d typically want to use, say, auto-incremented id columns or database sequences to generate the id values for your entities. For my example, I am using a MySQL database, and all of my id columns are set to auto increment. To reflect this in my entity model, I can use an additional annotation called @GeneratedValue in the id property. This tells JPA that the id value for this entity will be automatically generated by the database during the insert, and it should fetch that id after the insert using a select command.

With the above modifications, my entity class becomes something like this –

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

@Entity
public class Address {
  @Id
  @GeneratedValue
  private Integer id;

  // Rest of the class code........

And the insert procedure becomes this –

Address anotherAddress = new Address()
    .setCity("Shinagawa-ku, Tokyo")
    .setCountry("Japan")
    .setPostcode("140-0002")
    .setStreet("Shinagawa Seaside Area");
em.getTransaction()
    .begin();
em.persist(anotherAddress);
em.getTransaction()
    .commit();

How did JPA figure out which table to use to save Address entities? Turns out, it’s pretty straight-forward –

  1. When no explicit table information is provided with the mapping then JPA tries to find a table whose name matches with the entity name.
  2. The name of an entity can be explicitly specified by using the “name” attribute of the @Entity annotation. If no name attribute is found, then JPA assumes a default name for an entity.
  3. The default name of an entity is the simple name (not fully qualified name) of the entity class, which in our case is Address. So our entity name is then determined to be “Address”.
  4. Since our entity name is “Address”, JPA tries to find if there is a table in the database whose name is “Address” (remember, most of the cases database table names are case-insensitive). From our schema, we can see  that this is indeed the case.

So how did JPA figure our which columns to use to save property values for address entities?

At this point I think you will be able to easily guess that. If you cannot, stay tuned for my next post!

Until next time.

[ Full working code can be found at github.]

In my previous article, I have written a sample example showing how to configure JPA for running it in a Java SE environment. I also showed a sample persistence.xml file which looks like below –

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
  http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
  version="2.1">

  <persistence-unit name="jpa-example" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

    <properties>
      <!-- Configuring JDBC properties -->
      <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/jpa_example" />
      <property name="javax.persistence.jdbc.user" value="root" />
      <property name="javax.persistence.jdbc.password" value="my_root_password" />
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />

      <!-- Hibernate properties -->
      <property name="hibernate.show_sql" value="true" />
      <property name="hibernate.format_sql" value="true" />
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
      <property name="hibernate.hbm2ddl.auto" value="validate" />

      <!-- Configuring Connection Pool -->
      <property name="hibernate.c3p0.min_size" value="5" />
      <property name="hibernate.c3p0.max_size" value="20" />
      <property name="hibernate.c3p0.timeout" value="500" />
      <property name="hibernate.c3p0.max_statements" value="50" />
      <property name="hibernate.c3p0.idle_test_period" value="2000" />
    </properties>
  </persistence-unit>
</persistence>

Those who are only starting out on JPA, please let me explain some of the components of this configuration.

The first section is used for configuring JDBC connection that will be used by the persistence provider. Usually we specify the JDBC url, database username, password and fully qualified name of the Driver class in this section. The second section configures some property values for hibernate, and is explained below –

  1. The “hibernate.show_sql” property specifies whether or not hibernate will print the queries in the log file (provided that you have configured log4j properly). This is specially helpful if you want to view which queries are being executed for reading/writing/deleting some entities. In the production environment you can set to false if you want so that the queries will not be logged.
  2. The “hibernate.format_sql” property specifies whether or not the queries will be formatted to a more readable form before logging.
  3. The “hibernate.dialet” property specifies which type of dialects we intend to use. If you do not know what they are then please read this excellent answer on StackOverflow.
  4. The “hibernate.hbm2ddl.auto” property is very interesting one. By changing its value you can enable hibernate to create/drop your database tables for you, or validate an existing schema against your mapping. This has also been explained very well on StackOverflow.

The last section configures the connection pool that hibernate will use for the database. Hibernate usually provides a built-in connection pooling mechanism which is good enough for development and testing, but is not suitable for production environment. So to get the optimal connection pooling behavior in production you need to use something more mature. C3P0 is a popular production-grade connection pooling library which is very easy to use with Hibernate. All you need to do is just specify the property values like minimum/maximum number of connections in the pool, timeout values etc., and the rest will be taken care of by Hibernate.

There is also another important point that I have skipped in the last article. In order for the entities to be found by the persistence provider in a Java SE environment, they will have to be listed in the persistence.xml file as follows –

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
  http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
  version="2.1">

  <class>fully.qualified.path.of.the.entity</class>

  <!-- rest of the contents -->
  
  </persistence-unit>
</persistence>

Doing this will ensure that your entities will be found by the persistence provider and will be ready for persistence. However, hibernate auto-scans the packages for classes marked with the “Entity” annotation and make them persistent, so we did not have to worry about that. Keep in mind that this is also the case when you use JPA in a Java EE environment (i.e., your application runs in a full-blown application server). In this case the application server scans the application during its deployment and finds the classes marked as entities. If you run your application in a Java SE environment using a provider which does not have this type of auto scanning ability, then you will be required to list the entities in the persistence.xml file like above.

That’s it for setting up JPA in a Java SE environment. Hopefully once you have this setup you will be easily able to persist your entities without much trouble.

JPA stands for Java Persistence API, which basically is a specification that describes a way to persist data into a persistent storage, usually a database. We can think of it as something similar to ORM tools like Hibernate, except that it is an official part of the Java EE specification (and it’s also supported on Java SE).

There are many reasons to learn an ORM tool like JPA. I will not go into the details of this because there are already many posts on the web which perfectly answer this question, like this one, or this one. However, we should also keep in mind that this is not a single magic bullet which will solve our every problem.

When I first started out with JPA, I had real difficulties to set it up because most of the articles on the web are written for Java EE environment only, whereas I was trying to use it in a Java SE environment. I hope that this article will be helpful for those who wish to do the same in the future.

In this example we will use Maven to set up our required dependencies. Since JPA is only a specification, we will also need an implementation. There are many good implementations of JPA available freely (like EclipseLink, Hibernate etc.). For this article I have chosen to use Hibernate. As for the database, I will use MySQL.

Let us first create a simple maven project. I have created mine using the quick start archetype from the command line. If you do not know how to do that, you can follow this tutorial.

OK, so let us get the dependencies for the JPA next. Include the following lines in your pom.xml –

<dependency>
  <groupId>javax.persistence</groupId>
  <artifactId>persistence-api</artifactId>
  <version>1.0.2</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>4.3.6.Final</version>
  <exclusions>
    <exclusion>
      <groupId>org.hibernate.javax.persistence</groupId>
      <artifactId>hibernate-jpa-2.1-api</artifactId>
    </exclusion>
  </exclusions>
</dependency>

The first dependency specifies the standard JPA interface, and the second one specifies the implementation. Including JPA dependencies this way is desirable because it gives us the freedom to switch vendor-specific implementation in the future without much problem (see details here). However we will not be able to use the latest version of the API this way because the API version 1.0.2 is the last version that is released as an independent JAR. At the time of writing this article, the latest version of the JPA specification is 2.1 which is not available independently (there are lots of requests for it though). If we want to use that one now then our only options are to choose from either a vendor-specific JAR or use an application server which provides the API along with its implementation. I have decided to use the API specification provided by Hibernate. In that case including only the following dependency will suffice –

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>4.3.6.Final</version>
</dependency>

Next step is to include the dependency for MySQL. Include the following lines in your pom.xml –

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.31</version>
</dependency>

After including the rest of the dependencies (i.e., jUnit, Hamcrest etc.) the full pom.xml looks like below –

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.keertimaan.javasamples</groupId>
  <artifactId>jpa-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>jpa-example</name>
  <url>https://sayemdb.wordpress.com</url>

  <properties>
    <java.version>1.8</java.version>
    <hibernate.version>4.3.6.Final</hibernate.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <!-- JPA -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>${hibernate.version}</version>
    </dependency>

    <!-- For connection pooling -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-c3p0</artifactId>
      <version>${hibernate.version}</version>
    </dependency>

    <!-- Database -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.31</version>
    </dependency>

    <!-- Test -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <groupId>org.hamcrest</groupId>
          <artifactId>hamcrest-core</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest-all</artifactId>
      <version>1.3</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.5.1</version>
        <configuration>
          <source>${java.version}</source>
          <target>${java.version}</target>
          <compilerArgument>-Xlint:all</compilerArgument>
          <showWarnings>true</showWarnings>
          <showDeprecation>true</showDeprecation>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Now it’s time to configure our database. I will use the following schema in all of my future JPA examples which I found from this excellent online book

Database Schema

Database Schema

Create an equivalent database following the above schema in your local MySQL installation.

Our next step is to create the persistence.xml file which will contain our database specific information for JPA to use. By default JPA expects this file to be in the class path under the META-INF folder. For our maven project, I have created this file under project_root/src/main/resources/META-INF folder –

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
  http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
  version="2.1">

  <persistence-unit name="jpa-example" transaction-type="RESOURCE_LOCAL">
  <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

  <properties>
    <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/jpa_example" />
    <property name="javax.persistence.jdbc.user" value="root" />
    <property name="javax.persistence.jdbc.password" value="my_root_password" />
    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />

    <property name="hibernate.show_sql" value="true" />
    <property name="hibernate.format_sql" value="true" />
    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
    <property name="hibernate.hbm2ddl.auto" value="validate" />

    <!-- Configuring Connection Pool -->
    <property name="hibernate.c3p0.min_size" value="5" />
    <property name="hibernate.c3p0.max_size" value="20" />
    <property name="hibernate.c3p0.timeout" value="500" />
    <property name="hibernate.c3p0.max_statements" value="50" />
    <property name="hibernate.c3p0.idle_test_period" value="2000" />
    </properties>
  </persistence-unit>
</persistence>

The above file requires some explanation if you are an absolute begineer in JPA. In my next article I will try to explain it as much as possible, but for running this example you will only need to change the first three property values to match your environment (namely the database name, username and password). Also keep a note of the value of the name attribute of the persistence-unit element. This value will be used to instantiate our EntityManagerFactory instance later in the code.

Ok, let us now create an entity to test our configuration. Create a class called Address with the following contents –

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

@Entity
@Table(name = "address")
public class Address {
  @Id
  @GeneratedValue
  private Integer id;

  private String street;
  private String city;
  private String province;
  private String country;
  private String postcode;

  /**
   * @return the id
   */
  public Integer getId() {
    return id;
  }

  /**
   * @param id the id to set
   */
  public Address setId(Integer id) {
    this.id = id;
    return this;
  }

  /**
   * @return the street
   */
  public String getStreet() {
    return street;
  }

  /**
   * @param street the street to set
   */
  public Address setStreet(String street) {
    this.street = street;
    return this;
  }

  /**
   * @return the city
   */
  public String getCity() {
    return city;
  }

  /**
   * @param city the city to set
   */
  public Address setCity(String city) {
    this.city = city;
    return this;
  }

  /**
   * @return the province
   */
  public String getProvince() {
    return province;
  }

  /**
   * @param province the province to set
   */
  public Address setProvince(String province) {
    this.province = province;
    return this;
  }

  /**
   * @return the country
   */
  public String getCountry() {
    return country;
  }

  /**
   * @param country the country to set
   */
  public Address setCountry(String country) {
    this.country = country;
    return this;
  }

  /**
   * @return the postcode
   */
  public String getPostcode() {
    return postcode;
  }

  /**
   * @param postcode the postcode to set
   */
  public Address setPostcode(String postcode) {
    this.postcode = postcode;
    return this;
  }
}

This class has been properly mapped to the address table and its instances are fully ready to be persisted in the database. Now let us create a helper class called PersistenceManager with the following contents –

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public enum PersistenceManager {
  INSTANCE;

  private EntityManagerFactory emFactory;

  private PersistenceManager() {
    // "jpa-example" was the value of the name attribute of the
    // persistence-unit element.
    emFactory = Persistence.createEntityManagerFactory("jpa-example");
  }

  public EntityManager getEntityManager() {
    return emFactory.createEntityManager();
  }

  public void close() {
    emFactory.close();
  }
}

Now let us write some sample persistence code in our Main method to test everything out –

import javax.persistence.EntityManager;

public class Main {
  public static void main(String[] args) {
    Address address = new Address();
    address.setCity("Dhaka")
        .setCountry("Bangladesh")
        .setPostcode("1000")
        .setStreet("Poribagh");

    EntityManager em = PersistenceManager.INSTANCE.getEntityManager();
    em.getTransaction()
        .begin();
    em.persist(address);
    em.getTransaction()
        .commit();

    em.close();
    PersistenceManager.INSTANCE.close();
  }
}

If you check your database, you will see that a new record has been inserted in your address table.

This article explains how to set up JPA without using any other frameworks like Spring. However it is a very good idea to use Spring to set up JPA because in that case we do not need to worry about managing entity managers, transactions etc. Beside setting up JPA, spring is also very good for many other purposes too.

That’s it for today. In the next article I will try to explain the persistence.xml file and the corresponding configuration values as much as possible. Stay tuned!

The full code can be found at github.