JPA Getting Started Guide (v5.2)

Developing applications is, in general, a complicated task, involving many components. Developing all of these components can be very time consuming.
The Java Persistence API (JPA) was designed to alleviate some of this time spent, providing an API to allow java developers to persist object-oriented
data into relational databases (RDBMS).

DataNucleus JPA provides an implementation of this JPA standard, allowing you, the user, to persist your
object-oriented data to not only the RDBMS datastores the standard was intended for, but also to a wide range of other datastores.
These include popular map stores such as Cassandra and HBase, the Neo4j graph store, spreadsheets in Excel or OpenDocument formats,
JSON formatted Amazon and Google Storage options, the popular MongoDB JSON-like document store, as well as ubiquitous LDAP and more besides.
DataNucleus was the first JPA provider to support persistence to non-RDBMS datastores, and still has a wider range of supported stores than any other JPA provider.

DataNucleus doesn’t purport to be the best solution to every problem.
For example, where you want to bulk persist large amounts of data then other solutions that get closer to the datastore API would be more appropriate.
Where you want to tailor the precise query sent to the datastore to take advantage of some datastore-specific feature is another situation
in which you may find a hand-crafted solution more appropriate.
That said, the range of capabilities of DataNucleus JPA cover a wide range of use-cases, the barrier to entry for use of DataNucleus is very low.
You do not need to necessarily be an expert in all features of the chosen datastore to use it. It shields you from the majority of the
more routine handling, whilst still letting you have a high degree of control over its behaviour and we hope that you benefit from its features.

Key Points

There are some key points to bear in mind when starting using JPA for java persistence.

Your classes should be exactly that, your classes. DataNucleus imposes little to nothing on you. Some JPA providers insist on a
default constructor, but DataNucleus provides its enhancer to add that automatically when not present.

Your JPA entity classes need bytecode enhancing for use in the persistence process, but this can be an automatic post-compilation step.

To persist objects of classes you firstly need to define which classes are persistable, and how they are persisted.
Start under the JPA Mapping Guide

The persistence itself is controlled by an EntityManager and each object to be persisted will
have different lifecycle states that you need to have an understanding of.

You retrieve objects either by their identity, or using a query. With JPA you can use JPQL or SQL query languages

You will need javax.persistence as well as datanucleus-api-jpa, datanucleus-core and the datanucleus-XXX jar for whichever datastore you are using.

Understanding the JARs

DataNucleus has a modular architecture and you will need to make use of multiple JARs in your application, as follows

javax.persistence.jar : This is the JPA API. This is basically a collection of interfaces, annotations and helper classes.

datanucleus-api-jpa.jar : This is DataNucleus' implementation of the JPA API. It implements the interfaces defined in javax.persistence.jar.

datanucleus-core.jar : This provides the basic DataNucleus persistence mechanism, and is required by all DataNucleus plugins.

datanucleus-{datastore}.jar ({datastore} is 'rdbms', 'mongodb', 'cassandra', etc) : This provides persistence to the specific type of datastore that the JAR is for.

datanucleus-jpa-query.jar : This provides an annotation processor and is used by the JPA Criteria mechanism to generate the JPA static metamodel classes used at runtime.

There are various additional JARs that can be used, providing support for additional (non-standard) types, or features (such as third-party caching products).

DataNucleus jars make use of a plugin mechanism, whereby they have a file plugin.xml that defines capabilities of each jar.
Attempting to "merge" the DataNucleus jars can result in problems, and people are advised to not do this, or if they really want to then use something like
one-jar.

JPA Tutorial (v5.2)

Background

An application can be JPA-enabled via many routes depending on the development process of the project in question.
For example the project could use Eclipse as the IDE for developing classes.
In that case the project would typically use the Dali Eclipse plugin coupled with the DataNucleus Eclipse plugin.
Alternatively the project could use Ant, Maven or some other build tool.
In this case this tutorial should be used as a guiding way for using DataNucleus in the application. The JPA process is quite straightforward.

Step 7 : Generate the database tables where your classes are to be persisted

The tutorial guides you through this. You can obtain the code referenced in this tutorial from
SourceForge (one of the files entitled "datanucleus-samples-jpa-tutorial-*").

Step 0 : Download DataNucleus AccessPlatform

You can download DataNucleus in many ways, but the simplest is to download the distribution ZIP appropriate to your datastore (in this case RDBMS).
You can do this from the SourceForge DataNucleus download page
When you open the zip you will find DataNucleus jars in the lib directory, and dependency jars in the deps directory.

Step 1 : Take your model classes and mark which are persistable

For our tutorial, say we have the following classes representing a store of products for sale.

So we have a relationship (Inventory having a set of Products), and inheritance (Product-Book).
Now we need to be able to persist objects of all of these types, so we need to define persistence for them.
There are many things that you can define when deciding how to persist objects of a type but the essential parts are

Mark the class as an Entity so it is visible to the persistence mechanism

Identify which field(s) represent the identity of the object.

So this is what we do now. Note that we could define persistence using XML metadata, annotations. In this tutorial we will use annotations.

Note that we mark each class that can be persisted with @Entity and their primary key field(s) with @Id.
In addition we defined a valueStrategy for Product field id so that it will have its values generated automatically.
In this tutorial we are using application identity which means that all objects of these classes will have their identity defined by the primary key field(s).
You can read more in the application identity guide when mapping your systems persistence.

Step 2 : Define the 'persistence-unit'

Writing your own classes to be persisted is the start point, but you now need to define which objects of these classes are actually persisted.
You do this via a file META-INF/persistence.xml at the root of the CLASSPATH. Like this

Step 3 : Enhance your classes

DataNucleus relies on the classes that you want to persist be enhanced to implement the interface Persistable.
You could write your classes manually to do this but this would be laborious.
Alternatively you can use a post-processing step to compilation that "enhances" your compiled classes, adding on the necessary extra methods to make them Persistable.
There are several ways to do this, most notably at post-compile, or at runtime. We use the post-compile step in this tutorial.
DataNucleus JPA provides its own byte-code enhancer for instrumenting/enhancing your classes (in datanucleus-core.jar) and this is included in the
DataNucleus AccessPlatform zip file prerequisite.

To understand on how to invoke the enhancer you need to visualise where the various source and metadata files are stored

This command enhances all classes defined in the persistence-unit "Tutorial".
If you accidentally omitted this step, at the point of running your application and trying to persist an object, you would get a ClassNotPersistableException
thrown. The use of the enhancer is documented in more detail in the Enhancer Guide.
The output of this step are a set of class files that represent persistable classes.

Step 4 : Write the code to persist objects of your classes

Writing your own classes to be persisted is the start point, but you now need to define which objects of these classes are actually persisted, and when.
Interaction with the persistence framework of JPA is performed via an EntityManager. This provides methods for persisting of
objects, removal of objects, querying for persisted objects, etc. This section gives examples of typical scenarios encountered in an application.

The initial step is to obtain access to an EntityManager, which you do as follows

So we created an EntityManagerFactory for our "persistence-unit" called "Tutorial" which we defined above.
Now that the application has an EntityManager it can persist objects. This is performed as follows

Please note that the finally step is important in that it tidies up connections to the datastore and the EntityManager.
Now we want to retrieve some objects from persistent storage, so we will use a "Query".
In our case we want access to all Product objects that have a price below 150.00 and ordering them in ascending order.

and so on. If you look at the persistence.xml of the downloadable sample project it has a full range of different datastores listed to uncomment as required

You can access the DataNucleus Log file by specifying the logging configuration properties, and any messages from DataNucleus will be output in the normal way.
The DataNucleus log is a very powerful way of finding problems since it can list all SQL etc actually sent to the datastore as well as many other parts of the persistence process.

Step 6 : Controlling the schema

We haven’t yet looked at controlling the schema generated for these classes.
Now let’s pay more attention to this part by defining XML Metadata for the schema.
In this example we define this in XML to separate schema information from persistence information (though could equally have used annotations if we really wanted to).
This information is used either to match up to an existing schema, or is used to generate a new schema (see #Step 7).
So we define a file META-INF/orm.xml at the root of the CLASSPATH. Like this

Step 7 : Generate any schema required for your domain classes

This step is optional, depending on whether you have an existing database schema. If you haven’t, at this point you can add the property
javax.persistence.schema-generation.database.action to your persistence.xml and set it to create and this will create the schema
for the specified classes when the EntityManagerFactory is created.
The first thing that you need is to update the src/main/resources/META-INF/persistence.xml file with your database details, and this property.

For other datastores, just look at the downloadable sample and uncomment as required.

Now we simply create the EntityManagerFactory as earlier.
This will generate the required tables, indexes, and foreign keys for the classes defined in the annotations and orm.xml Meta-Data file.

Any questions?

If you have any questions about this tutorial and how to develop applications for use with DataNucleus please read the online documentation since answers are to be found there.
If you don’t find what you’re looking for go to Groups.IO or Gitter.