Learning JPA by Modelling OKR Application

By Amit Kumar, Diksha Chauhan and Sakshi Grover

Xebia Engineers
Xebia Engineering Blog
6 min readSep 18, 2019

--

Photo by Estée Janssens on Unsplash

The Java Persistence API or JPA simplifies Java persistence and provides an object-relational mapping approach that lets you declaratively define how to map Java objects to relational database tables in a standard, portable way.

For the past few weeks, we have been learning about this API in Xebia. We would like to share what we have learnt so far through this blog. We hope reading through this blog will help you learn about JPA.

JPA is basically used to store, update, retrieve data from relational database. It provides an abstraction that significantly reduces the amount of boilerplate code that developers would have to write otherwise.

Some of the implementations of JPA are hibernate, Open JPA, Eclipse Link and many more. But, Hibernate is the most popularly used implementation of JPA.

Why to use JPA?

Below are a few reasons why we think you should use JPA.

  • Makes Database Programming easier

The main advantage of using JPA is that unlike JDBC (which uses tables and records to persist data), in JPA, the data is represented by classes and objects which significantly simplifies database programming.

  • Loosely coupled

JPA also gives us the flexibility to switch between various implementations making it loosely coupled. Having the ability to choose among the different vendor’s implementations, it gives us the power to innovate and use the best features.

  • Improves Developer Productivity

The reasons why JPA is popular for its developer productivity as they only have to focus on the object model without concerning ourselves about the relational database.. It also provides a simple but very efficient API to implement basic CRUD operations.

  • Database Independent

JPA provides a database independent abstraction on top of SQL. As long as you’re not using any native queries, you don’t have to worry about database portability. Your JPA implementation adapts the generated SQL statements in each API call or JPQL query to the specific database dialect and handles the different database-specific data types.

  • Supports Inheritance

We all know that relational databases do not support inheritance. JPA gives us the possibility to model parent child relationships using its inheritance support. It takes care of managing the underlying complexity related to inheritance.

How to use JPA?

Let us now understand how we can use JPA with the help of a small OKR application. To achieve this, we first need to understand what OKR is?

OKR (Objectives and Key Results) is a goal system used by various organisations to create alignment and engagement for specific time period around measurable goals.

It has two components

Objectives which are the qualitative description of what you want to achieve. On the contrary, Key Results are a set of metrics that measure your progress towards the Objective. For each Objective, there is a set of Key Results. All Key Results have to be quantitative and measurable.

Like, a team that wants to increase the engagement with a digital service

Objective could be ‘Delight our customers’

And to measure this we can have Key Results such as

  • Improve engagement (users that complete a full profile) from X to Y.
  • Improve average weekly visits per active user from X to Y

Now, as we start building our application, we can say that we need two entities viz. Objective and Key Result. We have assumed that these are applicable for a specific quarter.

These two entities will be associated with each other through a relationship. Here we will explore how to create JPA Entities and establish a relationship between them.

There are four types of relationships that exist in JPA.

One-to-One Relationship

One-to-One mapping has a single object reference in the source as well as the target entity. For example, An employee will have a unique access card.

It is denoted by @OneToOne annotation in Java class.

One-to-Many Relationship

In this relationship, each row of first entity can be referenced to many records in the other entity. For example, you can reach out to your friend at different addresses like at his office address or temporary house address or at the permanent address.

It is denoted by @OneToMany annotation in Java.

Many-to-One Relationship

As the name indicates, Many-to-One mapping is similar to One-to-Many.

Lets say, There can be many addresses of a single person where he can have his posts delivered.It is annotated by @ManyToOne.

Many-to-Many Relationship

Many-to-many relationship is defined on entities where different elements of that entity can be associated with various elements of another entity.

To understand this, we can take an example of Employee Department relationship where many employees can be in a specific department and also one employee can belong to multiple departments. It is annotated by @ManyToMany.

JPA in real-world: Modelling OKR JPA Entities

Now let’s create the entities Objective and Key results.

In Objective entity, we have used the following attributes

  • title which tells us what the objective is.
  • label to show what is the status of objective and
  • since we know, a specific objective can be measured using many keyresults, we have taken a list of key results.

On the other hand, In KeyResult entity, we have taken

  • title, again to tell about the key result
  • percentageFinished, to show the progress of Objective,
  • confidenceScore that reflects the confidence level to achieve the key result
  • and keyResult status.

Using this example, we have illustrated a One-to-Many relationship between Objective and KeyResult entities. To accomplish this, we need to have multiple KeyResults in Objective Entity as shown in the code snippet below.

Objective.java

KeyResult.java

Let us decode all annotations used above.

@Entity implies that the following class represents a table in the database whose name is given with @Table annotation. If the name is not mentioned then by default, it uses the class name as the table name.

Similarly, @Column signifies that the following fields represent columns of the table. Although this annotation is not mandatory but still can be used to provide custom name, length, nullable and many other parameters to a column.

@Id annotation is used to mark the field as primary key field. When a primary key field is defined, the primary key value is automatically injected into that field by ObjectDB.

@GeneratedValue(strategy = GenerationType.AUTO), signifies that the strategy of generating the primary key of the table would be picked by the database provider itself which makes it independent of the database we are using in our application.

Now let us discuss how we have defined the relationship between the above two entities. As we know, An Objective can have many Key Results so here we have used @OneToMany relationship as mentioned above. But at the same time, many Key Results can belong to a single Objective making this relationship bidirectional and that is why we have used @ManyToOne in KeyResult.java.

Going deep into the concept of relationship models, we found that relationships can be both unidirectional and bidirectional.

A unidirectional relationship is like a one way street. We can access target entity from source but vice versa is not possible whereas in case of bidirectional relationship, we can work both ways.

Since our entities have a bidirectional relationship, there must exist two sides to this relationship. One of them is an owner side i.e. it contains foreign key. In our example, it is KeyResult.java. We have used @JoinColumn to indicate that this entity is a foreign key owner.. Although, this annotation is not mandatory. If we don’t use it, JPA takes the attribute name as the default

The other side is called the inverse side. This is the one that doesn’t own the foreign key. In our case, it is Objective.java. We use mappedBy attribute in @OneToMany annotation to make it an inverse side.

Summary

Through this blog, we have seen that Java Persistence API introduces a wide range of capabilities. As the size of the application grows, JPA provides a simple and easy way to access and persist data in java applications.

This blog gives you plenty to think about JPA, but there’s a lot more to learn. We hope our blog proved helpful to you. Keep learning, keep exploring and keep experimenting.

--

--