➤ How to Code a Game
➤ Array Programs in Java
➤ Java Inline Thread Creation
➤ Java Custom Exception
➤ Hibernate vs JDBC
➤ Object Relational Mapping
➤ Check Oracle DB Size
➤ Check Oracle DB Version
➤ Generation of Computers
➤ XML Pros & Cons
➤ Git Analytics & Its Uses
➤ Top Skills for Cloud Professional
➤ How to Hire Best Candidates
➤ Scrum Master Roles & Work
➤ CyberSecurity in Python
➤ Protect from Cyber-Attack
➤ Solve App Development Challenges
➤ Top Chrome Extensions for Twitch Users
➤ Mistakes That Can Ruin Your Test Metric Program
Spring Data JPA Introduction | First let us see the difference between JDBC, JPA, Hibernate, and Spring Data JPA.
- JDBC works based on SQL Query, given by the Programmer.
- JPA (Specification given by Sun/Oracle), generates all SQLs based on operations.
- For a Specification, we must follow one implementation ie Hibernate.
- Even in Hibernate, the programmer has to do code manually for operations, transactions, pooling, etc.
- In Spring Data JPA, code is automated. It internally follows Hibernate with the JPA concept.
- If we compare JDBC-Project and JPA-Project, the number of lines of code inside JPA is less. Even error rate also. Whereas in JDBC manual SQL coding is required.
- We can not write code using only JPA, internally one Impl must be there.
- In JPA also some coding lines exist. Spring Data JPA can reduce them into a few lines.
- The difference between JPA (with Hibernate) and Spring Data JPA is the number of lines of code only. Spring Data JPA reduces coding lines.
Spring Data JPA:-
- Programmers need not to define code for basic database operations. Just provide model class/entity class and primary key with data type.
- It supports embedded databases like H2, HyperSQL (HSQL), and Apache Darby, so no download & installation is required. They are embedded/InMemory database/RAM database. Therefore, it is used only for development purposes, never used in production.
- It also supports custom query programming using Query methods (findBy), and @Query(JPQL/HQL, SQL).
Annotation:-
@Entity
: It maps our class using the database table.@Id
: It indicates the primary key.@Table
: To provide table details like name. It is optional, if we don’t provide the table name then class-name will become the table name.@Column
: To provide column details we can use this like column-name. It is optional. If we do not provide a column name, the default is variable-name.
Example of Using H2 Database
Use the spring starter to create the project and add the following dependencies:- Spring Data JPA, Lombok, Spring Web, and H2 database. To work with the H2 database, its dependency is required.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
Model class:-
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table(name = "emp")
public class Employee {
@Id
@Column(name = "eid")
private Integer empId;
@Column(name = "ename")
private String empName;
@Column(name = "esal")
private Double empSal;
}
In application.properties file:-
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.jpa.show-sql=true
Run the application and Enter the URL as:- http://localhost:8080/h2-console/
Click on Connect (if failed modify JDBC URL=jdbc:h2:mem:testdb)

After the successful connection, we can see the tables.

Spring Data JPA (DB Operations)
Datasource connection properties:-
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
# optional
spring.datasource.driver-class-name=
JPA Properties:-
spring.jpa.hibernate.ddl-auto=update
# optional
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
show-sql
: It is a boolean property. The default value is false. If we set it to true, then the generated SQL is displayed in the console.- Database Platform/Dialect: Dialect is a class that generates SQL queries when we perform the DB operation. Dialect classes exist in the package
org.hibernate.dialect
. Every database will have its own dialect. Adding dialect is optional, Spring will be able to configure them itself based on the given database. ddl-auto
:- create/update/validate/create-dropddl-auto=create
: When we run the application, it creates new tables. If already old tables exist then drop them and create a new one.ddl-auto=update
: When we run the application, it will check for old tables. If exist use the same, else create new tables.ddl-auo=validate
(ornone
): In this case, the application will not create/drop/alter. The programmer has to define manual SQL queries.ddl-auto= create-drop
: When we start the application:-- Drop Tables if they exist.
- Create new tables.
- Perform DB operations.
- At the end again drop tables.
For ddl-auto
validate(none) is the default value for the external database. If we use embedded DB (like H2) then the default is create-drop
.
SQL queries are database-dependent. If we write one SQL query for Oracle, it may/may not work for SQLServer DB. Dialect solves the above problem by generating queries at runtime. So, the dialect is different for every DB.
Spring Data JPA Example using MySQL
For your Module (Ex: Employee, Admin, Student ..etc) You do not have to define operations code. Just define an interface, that must implement one of the below interfaces:-
At the runtime, a class will be generated which will contain all the database operation logic.
Coding files:-
- Model class/Entity class
- Repository Interface
- Runner class for Testing operations
In this example, we will use MySQL table,
mysql> show databases;
mysql> create database test;
mysql> use test;
mysql> show tables;
mysql> select * from emp;
Use the spring starter to create a new project and add the following dependencies:- Spring Data JPA, Lombok, and MySQL database.
Properties file:-
# datasource properties
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
# jpa properties
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
Entity Class:-
package com.knowprogram.demo.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table(name = "emp")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer empId;
@Column(name = "ename")
private String empName;
@Column(name = "esal")
private Double empSal;
}
Which DataType can be used to create the primary key variable in Hibernate/JPA? Any class that is serializable can be used as the primary key.
Repository:-
T = Model className = Employee
ID = DataType(of PrimaryKey) = Integer
package com.knowprogram.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.knowprogram.demo.model.Employee;
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
}
Runner Class:-
package com.knowprogram.demo.runner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import com.knowprogram.demo.model.Employee;
import com.knowprogram.demo.repository.EmployeeRepository;
@Component
public class TestRunner implements CommandLineRunner {
@Autowired
private EmployeeRepository employeeRepository;
@Override
public void run(String... args) throws Exception {
Employee emp = new Employee();
emp.setEmpName("ABC");
emp.setEmpSal(200.0);
employeeRepository.save(emp);
}
}
It will use these queries:-
Hibernate:
drop table if exists emp
Hibernate:
create table emp (
emp_id integer not null auto_increment,
esal float(53),
ename varchar(255),
primary key (emp_id)
) engine=InnoDB
Hibernate:
insert
into
emp
(ename, esal)
values
(?, ?)

Hibernate Vs Spring Data JPA
If we use Hibernate we have to write code manually.
// Hibernate 5 with JPA
try {
EntityManagerFactory emf = HibernateUtil.getEmf();
EntityManager em = emf.createEntityManager();
EntityTransaction et = em.getTransaction();
et.begin();
Employee obj= new Employee();
...
em.persist(obj);
et.commit();
} catch(Exception e) {
sysout(e);
et.rollback();
}
In Hibernate, the programmer is writing code for operations manually. Now same code is going to be generated by Spring Data JPA. But it is asking for two inputs:-
- Model class Name = T = Employee
- PrimaryKey DataType = ID = Integer
public interface EmployeeRepository extends CrudRepository<Employee, Integer> {
}
At runtime, one class is generated using your inputs, ie called Proxy. (Dynamic Proxy).
class $1 implements EmployeeRepo {
public <S extends Employee> S save(S entity) {
Assert.notNull(entity, "Entity must not be null.");
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
}
- <S extends Employee> means: Employee object or its sub-class objects are allowed.
- <S super Employee> means: Employee objects or its superclass objects are allowed.
@Repository Annotation
We actually don’t need to add @Repository to the EmployeeRepository interface. Stereotype annotations (@Component, @Service, @Repository, @Controller, and @RestController) are never applied on the interface and abstract classes, they are used on concrete classes. This is because the Spring framework creates instances of these classes to manage as beans, and you can’t instantiate an interface or abstract class directly.
Spring Data JPA recognizes it as a repository based on it extending CrudRepository, JpaRepository, or other repository interfaces. Spring will automatically manage it as a repository bean, handling all the annotations and configurations behind the scenes. Therefore we don’t need @Repository in the EmployeeRepository interface. Then when we can use the @Repository annotation?
You’d use the @Repository annotation mainly on custom repository implementations or DAO (Data Access Object) classes that you manually define.
@Repository
public class CustomEmployeeRepositoryImpl implements CustomEmployeeRepository {
@PersistenceContext
private EntityManager em;
@Override
public List<Employee> findEmployeesCustom() {
// Custom query logic
return em.createQuery("FROM Employee").getResultList();
}
}
So, @Repository is particularly useful when you’re writing custom repository logic. For Spring Data repositories, like EmployeeRepository, Spring Data handles it all for you, no need to add the annotation explicitly.
If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!