Tuesday, June 9, 2015

JPA In Action

Basic Concepts

Before diving into greater details lets quickly walk through some basic classes and what they mean in JPA.

  • EntityManager - A class that manages the persistent state(or lifecycle) of an entity.
  • Persistence Unit - is a named configuration of entity classes.
  • Persistence Context - is a managed set of entity instances. The entities classes are part of the Persistence Unit configurations.
  • Managed Entities - an entity instance is managed if it is part of a persistence context and that Entity Manager can act upon it.

A Very Simple Example

Let us create a very simple Employee table.

To check, let us query the table using simple SQL language. Here's the result

Using JPA

First, create the persistence.xml file. This xml file contains information regarding the database server your JPA will connect to, including the user name and the password.

Important thing to notice here is the <persistence-unit> tag. A persistence.xml can have as many persistence unit depending on the number of database you are connecting to. (1) Note that after that, there are several properties with their corresponding names and values. The database driver and the URL is very much dependent on the vendor of the RDBMS you are using. And as the name implies, values for the user/password is the one you use for accessing your RDBMS.

  • To get things going, first declare an object of EntityManagerFactory:
  •     private EntityManager em;
        private EntityManagerFactory emf;

  • Initialize the EntityManagerFactor object using Persistence object's static method createEntityManagerFactory(String persistenceUnit);
  •     emf = Persistence.createEntityManagerFactory("AllanJPA");

  • Initialize the EntityManager object by calling createEntityManager() method of the EntityManagerFactory
  •     em = emf.createEntityManager();

There you go, that's the basic initialization for JPA. Now let us now try to see how to create Query objects and run a JQL using JPA. Note that for every transaction you need create a EntityTransaction object first. It is done in this manner:

    em.getTransaction().begin();

Afterwards, you can now create your Query object using the following statements:

    List emps= em.createQuery("select p from Employee p").getResultList();

Full source code will look something like these:

The main() method here to run retrieve():

And here is the output based on the table we have queried earlier:

Persisting

Let us try to create instances of Employee class, here's the class:

And the Employee class is mapped to a table in orm.xml

The objects declaration for the Employee class will look something like this:

Employee empRag = new Employee("Raggedy", "Anne", "Dressmaker", 14000.00,       sdf.parse("22/06/2010"));
Employee empAlbert = new Employee("Big", "Albert", "Musician", 122000.00,       sdf.parse("17/06/2013"));
Employee empRasel = new Employee("Rasel", "Case", "Pilot", 140000.00,       sdf.parse("14/04/2012"));
Employee empDavid = new Employee("David", "Levinson", "Technician", 256000.00,       sdf.parse("25/12/2014"));

Afterwards, as mentioned earlier, we must have a transaction:

      // Create Transaction
      em.getTransaction().begin();
      // Persist the objects

After that, we can call persist() method to persist (save) our data to the database:

      em.persist(empRag);
      em.persist(empAlbert);
      em.persist(empRasel);
      em.persist(empDavid);

The actual code snippet:

When you try to run the code, it would look something like:

Upon checking the database we have:

SEQUENCE

Generators

  • AUTO
  • SEQUENCE
  • TABLE
  • IDENTITY
  • UUID
  • CUSTOM
  • NONE

Here is a summary : the list of possible generation strategies:

AUTO (default): Tells Doctrine to pick the strategy that is preferred by the used database platform. The preferred strategies are IDENTITY for MySQL, SQLite and MsSQL and SEQUENCE for Oracle and PostgreSQL. This strategy provides full portability.

SEQUENCE: Tells Doctrine to use a database sequence for ID generation. This strategy does currently not provide full portability. Sequences are supported by Oracle and PostgreSql.

IDENTITY: Tells Doctrine to use special identity columns in the database that generate a value on insertion of a row. This strategy does currently not provide full portability and is supported by the following platforms:

  • MySQL/SQLite => AUTO_INCREMENT
  • MSSQL => IDENTITY
  • PostgreSQL => SERIAL

TABLE: Tells Doctrine to use a separate table for ID generation. This strategy provides full portability. This strategy is not yet implemented!

NONE: Tells Doctrine that the identifiers are assigned, and thus generated, by your code. The assignment must take place before a new entity is passed to EntityManager#persist. NONE is the same as leaving off the @GeneratedValue entirely.

An object id (OID) is something that uniquely identifies an object. Within a VM this is typically the object's pointer. In a relational database table, a row is uniquely identified in its table by its primary key. When persisting objects to a database you need a unique identifier for the objects, this allows you to query the object, define relationships to the object, and update and delete the object. In JPA the object id is defined through the @Id annotation or element and should correspond to the primary key of the object's table.

Example id annotation

     ...
@Entity
public class Employee {
     @Id
     private long id;
     ...
}

Example id XML

<entity name="Employee" class="org.acme.Employee" access="FIELD">
       <attributes>
         <id name="id"/>
       </attributes>
<entity/>

Sequencing

An object id can either be a natural id or a generated id. A natural id is one that occurs in the object and has some meaning in the application. Examples of natural ids include email addresses, phone numbers, and social insurance numbers. A generated id (also known as a surrogate id) is one that is generated by the system. A sequence number in JPA is a sequential id generated by the JPA implementation and automatically assigned to new objects. The benefits of using sequence numbers are that they are guaranteed to be unique, allow all other data of the object to change, are efficient values for querying and indexes, and can be efficiently assigned. The main issue with natural ids is that everything always changes at some point; even a person's social insurance number can change. Natural ids can also make querying, foreign keys and indexing less efficient in the database.

In JPA an @Id can be easily assigned a generated sequence number through the @GeneratedValue annotation, or element.

Example generated id annotation

     ...
@Entity
public class Employee {
     @Id
     @GeneratedValue
     private long id;
     ...
}

Example id XML

<entity name="Employee" class="org.acme.Employee" access="FIELD">
       <attributes>
         <id name="id">
            <generated-value/>
         </id>
       </attributes>
<entity/>

Sequence Strategies

There are several strategies for generating unique ids. Some strategies are database agnostic and others make use of built-in databases support.

JPA provides support for several strategies for id generation defined through the GenerationType enum values: TABLE, SEQUENCE and IDENTITY. The choice of which sequence strategy to use is important as it affects performance, concurrency and portability.

1. Sequence objects

Sequence objects use special database objects to generate ids. Sequence objects are only supported in some databases, such as Oracle, DB2, and Postgres. Usually, a SEQUENCE object has a name, an INCREMENT, and other database object settings. Each time the .NEXTVAL is selected the sequence is incremented by the INCREMENT.

Sequence objects provide the optimal sequencing option, as they are the most efficient and have the best concurrency, however they are the least portable as most databases do not support them. Sequence objects support sequence preallocation through setting the INCREMENT on the database sequence object to the sequence preallocation size.

In JPA the @SequenceGenerator annotation or element is used to define a sequence object. The SequenceGenerator defines a sequenceName for the name of the database sequence object, and an allocationSize for the sequence preallocation size or sequence object INCREMENT.

Example sequence generator annotation

     ...
@Entity
public class Employee {
     @Id
     @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="EMP_SEQ")
     @SequenceGenerator(name="EMP_SEQ", sequenceName="EMP_SEQ", allocationSize=100)
     private long id;
     ...
}

Example sequence generator XML

<entity name="Employee" class="org.acme.Employee" access="FIELD">
       <attributes>
          <id name="id">
             <generated-value strategy="SEQUENCE" generator="EMP_SEQ"/>
             <sequence-generator name="EMP_SEQ" sequence-name="EMP_SEQ" allocation-size="100"/>
          </id>
       </attributes>
<entity/>
More on SEQUENCING here

Monday, June 8, 2015

JPA And Identities

JPA

Is a source to store business entities as relational entities. It shows how to define a POJO as an entity and how to manage entities with relations. It is also a vendor-independent specifications for mapping Java Objects to the tables TABLES of a relational database.

JPA itself is just a specification, not a product; it cannot perform persistence or anything else by itself. JPA is just a set of interfaces, and requires an implementation. There are open-source and commercial JPA implementations to choose from and any Java EE 5 application server should provide support for its use. JPA also requires a database to persist to.

JPA allows POJO (Plain Old Java Objects) to be easily persisted without requiring the classes to implement any interfaces or methods as the EJB 2 CMP specification required. JPA allows an object's object-relational mappings to be defined through standard annotations or XML defining how the Java class maps to a relational database table. JPA also defines a runtime EntityManager API for processing queries and transaction on the objects against the database. JPA defines an object-level query language, JPQL, to allow querying of the objects from the database.

There are many persistence products to choose from. Most persistence products now support a JPA interface, although there still are some exceptions. Which product you use depends on your preference, but most people would recommend you use the JPA standard whichever product you choose. This gives you the flexibility to switch persistence providers, or port your application to another server platform which may use a different persistence provider.

Class Level Architecture

The following image shows the class level architecture of JPA. It shows the core classes and interfaces of JPA.

The following table describes each of the units shown in the above architecture.


Units Description
EntityManagerFactory This is a factory class of EntityManager. It creates and manages multiple EntityManager instances.
EntityManager It is an Interface, it manages the persistence operations on objects. It works like factory for Query instance.
Entity Entities are the persistence objects, stores as records in the database.
EntityTransaction It has one-to-one relationship with EntityManager. For each EntityManager, operations are maintained by EntityTransaction class.
Persistence This class contain static methods to obtain EntityManagerFactory instance.
Query This interface is implemented by each JPA vendor to obtain relational objects that meet the criteria.

ORM (Object Relational Mapping)

Object-relational mapping (ORM) is a mechanism that makes it possible to address, access and manipulate objects without having to consider how those objects relate to their data sources. ORM lets programmers maintain a consistent view of objects over time, even as the sources that deliver them, the sinks that receive them and the applications that access them change.

As stated JPA is just a specification, meaning there is no implementation. You can annotate your classes as much as you would like with JPA annotations, however without an implementation nothing will happen. Think of JPA as the guidelines that must be followed or an interface, while Hibernate's JPA implementation is code that meets the API as defined by the JPA specification and provides the under the hood functionality.

When you use Hibernate with JPA you are actually using the Hibernate JPA implementation. The benefit of this is that you can swap out Hibernate's implementation of JPA for another implementation of the JPA specification. When you use straight Hibernate you are locking into the implementation because other ORMsmay use different methods/configurations and annotations, therefore you cannot just switch over to another ORM.

Next Topic SEQUENCE In JPA

Friday, June 5, 2015

Install EclipseLink

From your Eclipse IDE, click on File --> New --> JPA Project











Place the project name and choose the appropriate Runtime from the drop-down menu.





















Then click on Next button, you will see the JPA Facet tab. An error message will appear on top requiring persistence related libraries, click on the 'floppy disk' icon do download the latest EclipseLink related jar files


Accept the License Agreement and the download should start


Basically, that's it. You have successfully installed EclipseLink, an ORM distribution from Eclipse.