JPA is a Java specification(Jakarta Persistence API) and it manages relational data in Java applications. To access and persist data between Java object(Plain Old Java object)/ class and relational database, we can use JPA. Upon Object-Relation Mapping (ORM), it follows the mechanisms. It has the runtime EntityManager API and it is responsible for processing queries and transactions on the Java objects against the database. The main highlight is it uses JPQL (Java Persistent Query Language) which is platform-independent. JPA mainly covers persistence in terms of
- The Java Persistence API
- Object-Relational metadata
- Moreover under the persistence package API is defined.
- We cannot say that JPA is a framework, but It defines a concept and it can be implemented by any framework.
Advantages of Using JPA
- No need to write DDL/DML queries, instead we can map by using XML/annotations.
- JPQL is used and since it is platform-independent, we no need to depend on any native SQL table. Complex expressions and filtering expressions are all handled via JPQL only.
- Entity can be partially stored in one database like MySQL and the rest can be in Graph database Management System.
- Dynamic generation of queries is possible.
- Integration with Spring framework is easier with a custom namespace.
Units comprised in JPA are available under javax persistence package:
Persistence |
It has static methods to obtain an EntityManagerFactory instance |
EntityManagerFactory |
Factory class for EntityManager and responsible for managing multiple instances of EntityManager |
EntityManager |
It is an interface that works for the Query instance |
Entity |
They are persistent objects and stored as records in the database |
Persistence Unit |
Set of all entity classes |
EntityTransaction |
It has one-to-one relationship with EntityManager. |
Query |
To get relation objects that meet the criteria. |
Many have a confusion between JPA and HIbernate. Let us see few key differences
JPA
|
Hibernate
|
JPA : It is a Java specification for mapping relational data in Java application. It is not a framework |
Hibernate is an ORM framework and in that way data persistence is possible. |
In JPA, no implementation classes are provided. |
In Hibernate, implementation classes are provided. |
Main advantage is It uses JPQL (Java Persistence Query Language) and it is platform-independent query language. |
Here it is using HQL (Hibernate Query Language). |
It is available under javax.persistence package. |
It is available under org.hibernate package. |
In Hibernate, EclipseLink, etc. we can see its implementation. |
Hibernate is the provider of JPA. |
Persistence of data is handled by EntityManager. |
Persistence of data is handled by Session. |
Let us see a sample application for a spring boot application with JPA.
Example Project
It is a maven-driven project
Project Structure:
pom.xml
XML
<? xml version = "1.0" encoding = "UTF-8" ?>
< modelVersion >4.0.0</ modelVersion >
< parent >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-parent</ artifactId >
< version >2.3.0.BUILD-SNAPSHOT</ version >
< relativePath />
</ parent >
< groupId >com.gfg</ groupId >
< artifactId >spring-data-jpa-example</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
< name >spring-data-jpa-example</ name >
< description >Demo project for Spring Boot</ description >
< properties >
< java.version >1.8</ java.version >
</ properties >
< dependencies >
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-data-jpa</ artifactId >
</ dependency >
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-web</ artifactId >
</ dependency >
< dependency >
< groupId >org.apache.derby</ groupId >
< artifactId >derby</ artifactId >
< scope >runtime</ scope >
</ dependency >
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-test</ artifactId >
< scope >test</ scope >
< exclusions >
< exclusion >
< groupId >org.junit.vintage</ groupId >
< artifactId >junit-vintage-engine</ artifactId >
</ exclusion >
</ exclusions >
</ dependency >
</ dependencies >
< build >
< plugins >
< plugin >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-maven-plugin</ artifactId >
</ plugin >
</ plugins >
</ build >
< repositories >
< repository >
< id >spring-milestones</ id >
< name >Spring Milestones</ name >
</ repository >
< repository >
< id >spring-snapshots</ id >
< name >Spring Snapshots</ name >
< snapshots >
< enabled >true</ enabled >
</ snapshots >
</ repository >
</ repositories >
< pluginRepositories >
< pluginRepository >
< id >spring-milestones</ id >
< name >Spring Milestones</ name >
</ pluginRepository >
< pluginRepository >
< id >spring-snapshots</ id >
< name >Spring Snapshots</ name >
< snapshots >
< enabled >true</ enabled >
</ snapshots >
</ pluginRepository >
</ pluginRepositories >
</ project >
|
Let us see the key important files in the project. Starting with POJO class
GeekUserRecord.java
Java
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class GeekUserRecord {
@Id
private int id;
private String name;
private String email;
private String gender;
private int numberOfPosts;
public String getGender() { return gender; }
public void setGender(String gender)
{
this .gender = gender;
}
public int getNumberOfPosts() { return numberOfPosts; }
public void setNumberOfPosts( int numberOfPosts)
{
this .numberOfPosts = numberOfPosts;
}
public GeekUserRecord() {}
public int getId() { return id; }
public void setId( int id) { this .id = id; }
public String getName() { return name; }
public void setName(String name) { this .name = name; }
public String getEmail() { return email; }
public void setEmail(String email)
{
this .email = email;
}
}
|
Let us see the controller file now
GeekUserController.java
Java
import com.gfg.model.GeekUserRecord;
import com.gfg.service.GeekUserService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GeekUserController {
@Autowired private GeekUserService userService;
@RequestMapping ( "/" )
public List<GeekUserRecord> getAllUser()
{
return userService.getAllGeekUsers();
}
@RequestMapping (value = "/add-geekuser" ,
method = RequestMethod.POST)
public void
addUser( @RequestBody GeekUserRecord userRecord)
{
userService.addGeekUser(userRecord);
}
}
|
Let us see the service file
GeekUserService.java
Java
import com.gfg.model.GeekUserRecord;
import com.gfg.repository.GeekUserRepository;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class GeekUserService {
@Autowired
private GeekUserRepository geekUserRepository;
public List<GeekUserRecord> getAllGeekUsers()
{
List<GeekUserRecord> geekUserRecords
= new ArrayList<>();
geekUserRepository.findAll().forEach(
geekUserRecords::add);
return geekUserRecords;
}
public void addGeekUser(GeekUserRecord userRecord)
{
geekUserRepository.save(userRecord);
}
}
|
We need to add a repository file and it should extend CrudRepository
GeekUserRepository.java
Java
import com.gfg.model.GeekUserRecord;
import org.springframework.data.repository.CrudRepository;
public interface GeekUserRepository
extends CrudRepository<GeekUserRecord, String> {
}
|
Now, we need to execute this program and check the output. For that, we need to run the below file
SpringDataJPAExampleApplication.java
Java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringDataJPAExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDataJPAExampleApplication. class , args);
}
}
|
Right-click on the file and run the file as a Java application, we can see the output in the console.
Output:

The server started at port 8080
Initially as there are no records, when we hit http://localhost:8080, we wont be seeing any data. Let’s add the data by adding via the Postman client. Postman client has to be installed for doing this operation. URL to add users: http://localhost:8080/add-geekuser (Remember that this URL matches the controller file requestmapping).
Now a user is added. Hence we can verify the same by using http://localhost:8080
If we check with the added user detail and display user detail, they are same. If we have added more than 1 record, those records also will be displayed. In the whole project, we have not seen anywhere about the SQL statement like Insert(for adding)/Select(for retrieving). We need to have a POJO class. We have to possess the code with the important annotations as mentioned in the code. Automatically JPA (Java Persistence API) will take care of it.
Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape,
GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out -
check it out now!
Last Updated :
06 Jul, 2022
Like Article
Save Article