As a specification, the Java Persistence API focuses on Persistence, which decouples the creation process of Java objects from how they are created. Not all Java objects need to be persisted, but most applications retain key business objects. The JPA specification allows you to define which objects should be preserved and how they should be preserved in Java applications.

JPA itself is not a tool or framework; Instead, it defines a set of concepts that can be implemented by any tool or framework. Although JPA’s object relational mapping (ORM) model was originally based on Hibernate, it has evolved. Similarly, while JPA was originally intended for relational/SQL databases, some JPA implementations have been extended for NoSQL data stores. A popular framework for supporting JPA and NoSQL is EclipseLink, which is the reference implementation of JPA 2.2.

JPA or Hibernate

Hibernate and JPA are often confused because of their intertwined histories. However, like the Java Servlet specification, JPA produces a number of compatible tools and frameworks; Hibernate is just one of them.

Hibernate, developed by Gavin King and released in early 2002, is an ORM library for Java. King has developed Hibernate as an alternative to persistent entity beans. The framework was popular and much needed at the time, and many of its ideas were adopted and codified in the first JPA specification.

Today, Hibernate ORM is one of the most mature IMPLEMENTATIONS of JPA and remains a popular ORM option in Java. Hibernate ORM 5.3.8 (the current version at the time of this writing) implements JPA 2.2. In addition, Hibernate’s toolset has expanded to include popular tools such as Hibernate Search, Hibernate Validator, and Hibernate OGM, which supports NoSQL’s domain model persistence.

What is Java ORM?

Although their execution differs, each JPA implementation provides some kind of ORM layer. To understand JPA and JPA-compatible tools, you need to know ORM. Object-relational mapping is a task – and developers have good reason to avoid doing it manually. Frameworks such as Hibernate ORM or EclipseLink encode this task as a library or framework, the ORM layer. As part of the application architecture, the ORM layer is responsible for managing the transformation of software objects to interact with tables and columns in a relational database. In Java, the ORM layer transforms Java classes and objects so that they can be stored and managed in a relational database.

By default, the name of the persistent object becomes the name of the table, and the fields become columns. After the table is set up, each table row corresponds to an object in the application. Object maps are configurable, but defaults tend to work well.

Figure 1 illustrates the role of the JPA and ORM layers in application development.



Configure the Java ORM layer

When setting up a new project to use JPA, you need to configure the data store and THE JPA provider. You will configure the data store connector to connect to the database of your choice (SQL or NoSQL). You will also include and configure the JPA provider, which is a framework such as Hibernate or EclipseLink. Although you can configure JPA manually, many developers choose to use Spring’s out-of-the-box support. For a demonstration of manual and Spring-based JPA installation and setup, see “JPA Installation and Setup” below.

Java data Objects

Java Data Objects is a standardized persistence framework that differs from JPA primarily in its support for persistence logic in Objects and its long-standing support for using non-relational Data stores. JPA and JDO are similar enough that JDO providers often support JPA as well. See the Apache JDO project for more information about JDO as it relates to other persistence standards such as JPA and JDBC.

Data persistence in Java

From a programming perspective, the ORM layer is an adapter layer: it ADAPTS the language of object diagrams to the language of SQL and relational tables. The ORM layer allows object-oriented developers to build software that persists data without leaving the object-oriented paradigm.

With JPA, you can create mappings from the data store to the application’s data model objects. Instead of defining how objects are saved and retrieved, and then calling JPA to save them, you can define mappings between objects and databases. If you are using a relational database, most of the actual connection between the application code and the database will be handled by JDBC (Java Database Connection API). As a specification, JPA provides metadata annotations that you can use to define mappings between objects and databases. Each JPA implementation provides its own engine for JPA annotations. The JPA specification also provides a PersistanceManager, or EntityManager, which is a key point of contact with a JPA system (where your business logic code tells the system how to handle mapped objects).

To make all of this more concrete, consider Listing 1, a simple data class for modeling musicians.

Listing 1. A simple data class in Java

public class Musician {
  private Long id;
  private String name;
  private Instrument mainInstrument;
  private ArrayList performances = new ArrayList<Performance>();

  public Musician( Long id, String name){ /* constructor setters... */ }

  public void setName(String name){
    this.name = name;
  }
  public String getName() {return this.name;
  }
  public void setMainInstrument(Instrument instr){
    this.instrument = instr;
  }
  public Instrument getMainInstrument() {returnthis.instrument; } / /... Other getters and setters... }Copy the code

The Musician class in Listing 1 is used to hold the data. It can contain raw data, such as a name field. It can also maintain relationships with other classes, such as mainInstrument and Performances.

Musician exists because it contains data. Such classes are sometimes called Dtos or data transfer objects. Dtos are a common feature of software development. While they contain a variety of data, they do not contain any business logic. Persisting data objects is a common challenge in software development.



JDBC data persistence

One way to save instances of the Musician class to a relational database is to use the JDBC library. JDBC is an abstraction layer that allows applications to issue SQL commands regardless of the underlying database implementation.

Listing 2 shows how to persist the Musician class using JDBC.

Listing 2. JDBC for inserting records

Musician georgeHarrison = new Musician(0, "George Harrison");

    String myDriver = "org.gjt.mm.mysql.Driver";
      String myUrl = "jdbc:mysql://localhost/test";
      Class.forName(myDriver);
      Connection conn = DriverManager.getConnection(myUrl, "root"."");

      String query = " insert into users (id, name) values (? ,?) ";
      PreparedStatement preparedStmt = conn.prepareStatement(query);
      preparedStmt.setInt    (1, 0);
      preparedStmt.setString (2, "George Harrison");
      preparedStmt.setString (2, "Rubble");

      preparedStmt.execute();
      conn.close();

// Error handling removed for brevityCopy the code

The code in Listing 2 is quite self-documenting. The georgeHarrison object can come from anywhere (front-end commit, external service, etc.) and set its ID and name fields. The fields on the object are then used to provide the values of the SQL INSERT statement. (The PreparedStatement class is part of JDBC and provides a way to securely apply values to SQL queries.)

Although JDBC allows manual configuration of the included controls, it is cumbersome compared to JPA. To modify the database, you first need to create an SQL query that maps from Java objects to tables in a relational database. Then, whenever the object signature changes, the SQL must be modified. With JDBC, maintaining SQL becomes a task in itself.

JPA data persistence

Now consider Listing 3, where we use the JPA persistent Musician class.

Listing 3. Keeping George Harrison using JPA

Musician georgeHarrison = new Musician(0, "George Harrison");
musicianManager.save(georgeHarrison);Copy the code

Listing 3 replaces the manual SQL in Listing 2 with a line session.save(), which instructs JPA to persist the object. From then on, SQL transformations are handled by the framework, so you never have to leave the object-oriented paradigm.

Metadata annotations in JPA

Listing 3 is the result of the configuration, which was created using JPA annotations. Developers use annotations to tell JPA which objects to keep and how to keep them.

Listing 4 shows the Musician class with a single JPA annotation.

Listing 4. The @Entity annotation for JPA

@Entity public class Musician { // .. class body }Copy the code

Persistent objects are sometimes called entities. Attach @Entity to the class, Musician tells JPA that the class and its objects should be preserved.

Configure JPA

Like most modern frameworks, JPA follows convention coding (also known as convention over configuration), where the framework provides default configurations based on industry best practices. As an example, a class named Musician maps by default to a database table named Musician.

Traditional configuration is time saving, and it works well in many cases. You can also customize the JPA configuration. For example, you can use the @table annotation of JPA to specify the Table in which the Musician class should be stored.

Listing 5. The @table annotation for JPA

@Entity
@Table(name="musician") public class Musician { // .. class body }Copy the code

Listing 5 tells JPA to persist the entity (Musician class) into the Musician table.

A primary key

In JPA, a primary key is a field that uniquely identifies each object in the database. Primary keys can be used to reference objects and associate them with other entities. Whenever you store an object in a table, you also specify the field that you want to use as its primary key.

In Listing 6, we tell JPA which field to use as the Musician primary key.

Listing 6. Specifying the primary key

@Entity
public class Musician {
   @Id
   private Long id;Copy the code

In this case, we specify the Id field as the Musician primary key using JPA’s @ID annotation. By default, this configuration assumes that the primary key will be set by the database – for example, when the field is set to auto-increment on the table.

JPA supports other strategies for generating object primary keys. It also has comments for changing the names of individual fields. In general, JPA is flexible enough to accommodate any persistence mappings you might need.

CRUD operations

Once you map a class to a database table and establish its primary key, you have everything you need to create, retrieve, delete, and update that class in the database. Calling session.save() creates or updates the specified class, depending on whether the primary key field is null or applies to an existing entity. Calling entityManager.remove() removes the specified class.

Entity relationships in JPA

Simply using raw fields to persist objects is only half the equation. JPA also has the ability to manage related entities. There are four types of entity relationships in both tables and objects:

  1. More than a to
  2. Many a
  3. Many one-to-many
  4. One to one

Each type of relationship describes an entity’s relationship to another entity. For example, Musician entities can have a one-to-many relationship with entities represented by collections such as List or Set.

If Musician contains a Band field, the relationship between these entities can be many-to-one, meaning there is a Musician collection on a single Band class. (Assume each musician plays in only one band.)

If Musician contains the BandMates field, many-to-many relationships with other Musician entities can be represented.

Finally, Musician may have a one-to-one relationship with the Quote entity and is used to refer to a famousQuote: Quote famousQuote = new Quote().

Defining relationship types

JPA provides annotations for each relational mapping type. Listing 7 shows how to annotate a one-to-many relationship between Musician and Performances.

Listing 7. Annotate the one-to-many relationship

public class Musician {

  @OneToMany
  @JoinColumn(name="musicianId") private List<Performance> performances = new ArrayList<Performance>(); / /... }Copy the code

One thing to note is that @JoinColumn tells JPA which column on the Performance table will map to the Musician entity. Each performance will be associated with a single Musician from which the column is tracked. When JPA loads a Musician or a Performance into the database, it uses this information to rebuild the object graph.

Get the policy in JPA

In addition to knowing where to place related entities in the database, JPA also needs to know how to load them.

Access strategies
Tells JPA how to load related entities. When loading and saving objects, the JPA framework must be able to fine-tune how object graphs are handled. For example, if
Musician
Have a class
bandMate
Field (shown in Listing 7), load
george
Could lead to the whole
Musician
Table loads from database!

What we need is the ability to define lazy loading of related entities – recognizing, of course, that relationships in JPA can be eager or lazy. You can customize the extraction strategy using annotations, but the default configuration of JPA can usually be used directly without change:

  1. One-to-many: lazy
  2. Many to one: eager
  3. Many-to-many: lazy
  4. One to one: eager

JPA installation and setup

Finally, we’ll briefly cover how to install and set up JPA for Java applications. In this demo, I’ll use EclipseLink, the JPA reference implementation. A common way to install JPA is to include a JPA provider in your project. Listing 8 shows how to include EclipseLink as a dependency in the Maven pom.xml file.

Listing 8. Include EclipseLink as a Maven dependency

Org. Eclipse. Persistence eclipselink 2.5.0 - RC1Copy the code

You also need the driver that contains the database, as shown in Listing 9.

Listing 9. Maven dependencies for MySql connector

Mysql mysql connector - Java 5.1.32Copy the code

Next, you need to tell the system about your database and provider. This is done in the persistence.xml file, as shown in Listing 10.

Listing 10. Persistence. XML

http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> MyUnit" transaction-type="RESOURCE_LOCAL"> 
       
      javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/foo_bar"/> javax.persistence.jdbc.user" value=""/> javax.persistence.jdbc.password" value=""/> javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>   Copy the code

There are other ways to provide this information to the system, including programmatically. I recommend using this persistence.xml file because storing dependencies this way makes it easy to update the application without changing the code.

Spring configuration for JPA

Using Spring will greatly simplify JPA integration with applications. For example, placing the @SpringBootApplication annotation in the application header instructs Spring to automatically scan the classes based on the configuration you specify and inject EntityManager as needed.

If you want Spring to provide JPA support for your application, Listing 11 shows the dependencies to include.

Listing 11. Adding Spring JPA support to Maven

Org.springframework. boot spring-boot-starter 2.1.3.RELEASE org.springframework.boot spring-boot-starter-data-jpa 2.1.3. RELEASECopy the code

conclusion

Each application that works with a database should define an application layer whose sole purpose is to isolate persistence code. As you’ve seen in this article, the Java Persistence API introduces a number of features and supports Java object Persistence. Simple applications may not need all the functionality of JPA, and in some cases, the overhead of configuring the framework may not be worth it. However, as applications grow, JPA’s structure and packaging do stay the same. Using JPA simplifies the object code and provides a traditional framework for accessing data in Java applications.

English text: www.javaworld.com/article/337…

See more articles

Public id: Galaxy 1

Contact email: [email protected]

(Please do not reprint without permission)