Spring Data JPA Notes : A Complete Guide

Introduction to Spring Data JPA

Spring Boot JPA is a Java specification for managing relational database interactions in Java applications. It allows accessing and persisting data between Java objects and relational databases.
Follows Object-Relational Mapping (ORM) principles.

JPA β†’ Specification for ORM 
    β†“ 
Hibernate β†’ Implements JPA Specification 
    β†“
JDBC β†’ Interacts with the Database
    β†“ 
Data is stored in the Database

JPA Interfaces

JPA has two main interfaces:

1. CrudRepository : Provides pure CRUD (Create, Read, Update, Delete) functionality.

2. JPA Repository : Extends CrudRepository and provides sorting, searching, and pagination functionalities.

Common Hibernate Configurations

1. Hibernate DDL Auto Configuration

spring.jpa.hibernate.ddl-auto = update / create / validate / create-drop / none
  • update: Updates existing schema without deleting data.
  • create: Creates schema and removes old data.
  • validate: Validates schema but doesn’t make changes.
  • create-drop: Creates schema at startup and drops it at shutdown.
  • none: No automatic changes to the schema.

2. Show SQL Queries in Console

spring.jpa.show-sql = true
Enables logging of SQL queries executed by Hibernate.

3. Format SQL Queries

spring.jpa.properties.hibernate.format_sql = true
Formats SQL queries for better readability.

4. Set Hibernate Dialect (Optional)

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
Defines the SQL dialect Hibernate should use (MySQL, PostgreSQL, etc.).

Entity Annotations in Hibernate

@Entity β†’ Marks a class as a JPA entity.
@Table(name="employees") β†’ Specifies the database table name.
@Id β†’ Marks a field as the primary key.
@GeneratedValue(strategy = GenerationType.IDENTITY) β†’ Auto-generates primary key values.
@Column(name="name", nullable=false, length=50) β†’ Specifies column attributes.
@CreationTimestamp β†’ Automatically sets the creation timestamp.
@UpdateTimestamp β†’ Automatically sets the last updated timestamp.

XML and JSON Data Format

XML Data
  • XML data format is called SOAP (Simple Object Access Protocol) services.
  • SOAP is a protocol-independent service (supports HTTP, HTTPS, SMTP, FTP).
  • SOAP data is considered heavy-weighted.
JSON Data
  • JSON data is used in REST API services.
  • REST is protocol-dependent (HTTP, HTTPS).

CrudRepository in Spring Data JPA

CrudRepository<T, ID> is an interface provided by the Spring Data JPA module.
It is used for pure CRUD operations. 
It contains 11 methods: Implemented Methods in CrudRepository
  1. save(S entity)
  2. saveAll(Iterable<S> entities)
  3. findById(ID id)
  4. existsById(ID id)
  5. findAll()
  6. findAllById(Iterable<ID> ids)
  7. count()
  8. deleteById(ID id)
  9. delete(entity)
  10. deleteAll(Iterable<? extends T> entities)
  11. deleteAll()

JPA Repository

JpaRepository<T, ID> is an interface provided by Spring Data JPA. It extends CrudRepository and provides additional functionalities like sorting, searching, and pagination.

Implemented Methods in JPA Repository
  1. findAll()
  2. findAll(Sort sort)
  3. findAllById(Iterable<ID> ids)
  4. saveAll(Iterable<S> entities)
  5. flush()
  6. saveAndFlush(S entity)
  7. deleteInBatch(Iterable<T> entities)
  8. deleteAllInBatch()
  9. getOne(ID id)
  10. findAll(Example<S> example)
  11. findAll(Example<S> example, Sort sort)

Table-Level Annotations :

@Table(
    name = "employees",
    catalog = "emp_catalog",
    schema = "hr",
    uniqueConstraints = @UniqueConstraint(columnNames = "email"),
    indexes = @Index(name = "idx-name", columnList = "name")
)

catalog β†’ Specifies the database catalog.
schema β†’ Specifies the schema.
uniqueConstraints β†’ Enforces uniqueness on specified columns.
indexes β†’ Defines indexes for faster query performance.

Rules for Naming Query Methods in Spring Data JPA :

Method Names Should Start with Specific Prefixes

Use: findBy, readBy, queryBy, getBy
Examples:
  1. findByName()
  2. readByName()
  3. queryByName()
  4. getByName()
Limit Query Results Using Keywords

Use: First, Top before the attribute.
Examples:
  1. findFirstByName()
  2. findTop10ByName()
  3. Selecting Unique Results

Use: Distinct
Example:
  • findDistinctByName()
Combining Conditions with AND/OR
Examples:
  1. findByNameOrDescription()
  2. findByNameAndDescription()

Spring Boot CRUD Operation Example (MySQL Database)

Required Files
  1. Employee.java β†’ Defines Entity
  2. EmployeeRepo.java β†’ Repository interface
  3. application.properties β†’ Configuration file
  4. Application.java β†’ Main Spring Boot application
Required JARs
  1. Spring Web
  2. Spring Boot Dev Tools
  3. Spring Data JPA
  4. MySQL Driver

Example Code

1. Employee.java (Entity Class)

@Entity
public class Employee {
    @Id
    private int empId;
    private String empName;

    // Getters and Setters
}

2. Employee Repository (EmployeeRepo.java)

Purpose: Defines a repository interface for database operations.

Implementation:

@Repository
public interface EmployeeRepo extends CrudRepository<Employee, Integer> {
}

Using JpaRepository Instead of CrudRepository

@Repository
public interface EmployeeRepo extends JpaRepository<Employee, Integer> {
}

@Repository β†’ Marks this as a Spring Data repository.
Extends CrudRepository<Employee, Integer> for performing CRUD operations.

3. Application Startup (Application.java)

Purpose: Entry point for the Spring Boot application.

Implementation:

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private EmployeeRepo repo;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // Code to execute on startup
    }
}

@SpringBootApplication β†’ Enables Spring Boot auto-configuration.
@Autowired β†’ Injects EmployeeRepo dependency.

4. REST API Endpoint (EmployeeController.java)

Saving Employee Data (POST Request)

API Endpoint: POST http://localhost:9000/save

Example Request Body:
{
    "empId": 120,
    "empName": "Ravi"
}

Controller Code:

@RestController
public class EmployeeController {

    @Autowired
    private EmployeeService service;

    @PostMapping("/save")
    public void saveEmployee(@RequestBody Employee emp) {
        service.saveEmp(emp);
    }
}

@RestController β†’ Marks this as a REST API controller.
@Autowired β†’ Injects EmployeeService.
@PostMapping("/save") β†’ Maps POST requests to /save.
@RequestBody Employee emp β†’ Converts JSON input into a Java object.

5 Service Layer (EmployeeServiceImpl.java)

Purpose: Implements business logic.
Implementation:

@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeRepo repo;

    @Override
    public void saveEmp(Employee emp) {
        repo.save(emp);
    }
}

@Service β†’ Marks this as a business service.
Uses repo.save(emp) to persist data in the database.

Entity Relationships and Mapping in Hibernate

Understanding Entity Relationships
The below represents an ER Diagram that shows the relationships between Department, Employee, and Project entities.

Entities and Their Attributes

1.Department
  1. id (Long): Primary key.
  2. title (String): Name of the department.
  3. manager (Employee): One employee is the manager.
  4. workers (List<Employee>): A list of employees working in this department.
2.Employee
  1. id (Long): Primary key.
  2. name (String): Employee name.
  3. department (Department): Each employee belongs to one department.
  4. projects (List<Project>): An employee can work on multiple projects.
3.Project
  1. id (Long): Primary key.
  2. title (String): Name of the project.
  3. members (List<Employee>): Multiple employees can work on the same project.
Relationship Constraints :
  • One Department can have:
  • One manager (OneToOne).
  • Multiple workers (OneToMany).
  • One Employee can:
  • Belong to one department (ManyToOne).
  • Be a manager of one department (OneToOne).
  • Work on multiple projects (ManyToMany).
  • One Project can have multiple employees (ManyToMany).

Key Concepts of Entity Mapping in Hibernate

  • Entity: A class mapped to a database table.
  • Primary Key (@Id): Unique identifier for each entity.
  • Foreign Key: Reference to another entity.
  • Cascade: Defines cascading operations like delete, update.
  • Fetch Type:
  • EAGER: Loads related entities immediately.
  • LAZY: Loads related entities on demand.

Entity Class Implementations

@Entity
public class EmployeeEntity {
  
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @OneToOne(mappedBy = "manager")
    @JsonIgnore
    private DepartmentEntity managedDepartment;
}

Explanation:
@Entity: Defines this as a Hibernate entity.
@Id: Marks id as the primary key.
@GeneratedValue: Auto-generates primary key values.
@Column(nullable=false): Ensures name cannot be null.
@OneToOne(mappedBy = "manager"): Defines a bidirectional OneToOne relationship with DepartmentEntity.
@JsonIgnore: Prevents infinite recursion in JSON responses.

Department Entity

@Entity
public class DepartmentEntity {
  
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String title;

    @OneToOne
    @JoinColumn(name = "department_manager")
    private EmployeeEntity manager;
}

Explanation:
@JoinColumn(name = "department_manager"): Specifies the foreign key column linking to EmployeeEntity.
@OneToOne: Defines the relationship where one department has one manager.

Relationship Mapping in JPA

OneToMany (Department β†’ Employees)

@OneToMany(mappedBy = "department", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<EmployeeEntity> workers;

@OneToMany: One department can have multiple employees.
mappedBy = "department": This tells Hibernate that the department field in EmployeeEntity owns the relationship.
cascade = CascadeType.ALL: Any operation on DepartmentEntity (insert/update/delete) cascades to its employees.
fetch = FetchType.LAZY: Employees are loaded only when needed.

ManyToOne (Employee β†’ Department)

@ManyToOne
@JoinColumn(name = "department_id", nullable = false)
private DepartmentEntity department;
@ManyToOne: Many employees can belong to one department.
@JoinColumn(name = "department_id"): Specifies the foreign key column in the EmployeeEntity table.

ManyToMany (Employee ↔ Project)

@ManyToMany
@JoinTable(
    name = "employee_project",
    joinColumns = @JoinColumn(name = "employee_id"),
    inverseJoinColumns = @JoinColumn(name = "project_id")
)
private List<ProjectEntity> projects;
@ManyToMany: Many employees can be assigned to multiple projects.
@JoinTable: Defines the junction table employee_project.
joinColumns: Maps employee_id in the junction table.
inverseJoinColumns: Maps project_id in the junction table.

Download Handwritten Notes for Spring Data JPA

Download Notes