Spring Boot JPA Entity and Repository Setup with PostgreSQL

Introduction :

In the previous article, we successfully connected a PostgreSQL database with a Spring Boot application. Establishing the database connection is the first step toward building robust enterprise applications. However, manually writing SQL queries for every database operation can become time-consuming and difficult to maintain as applications grow.


Spring Data JPA simplifies database interactions by allowing developers to map Java classes directly to database tables and perform CRUD operations with minimal boilerplate code. Instead of writing repetitive SQL statements, developers can focus on business logic while Spring handles the database communication behind the scenes.

In this article, we will learn how to:

  • Understand JPA and Spring Data JPA

  • Create Entity classes

  • Create Repository interfaces

  • Configure PostgreSQL integration

  • Perform basic database operations

  • Understand the project structure and best practices

By the end of this tutorial, you will have a fully functional Spring Boot application capable of interacting with PostgreSQL using JPA entities and repositories.


What is JPA?

JPA (Java Persistence API) is a Java specification that provides a standard way to manage relational data in Java applications.

It allows developers to:

  • Map Java objects to database tables

  • Perform CRUD operations

  • Manage relationships between tables

  • Reduce boilerplate JDBC code

JPA itself is only a specification. To implement it, we use frameworks such as:

  • Hibernate (Most Popular)

  • EclipseLink

  • OpenJPA

In Spring Boot applications, Hibernate is the default JPA implementation.


What is Spring Data JPA?

Spring Data JPA is a Spring framework module built on top of JPA.

It significantly reduces the amount of code required for data access layers.

Without Spring Data JPA:

Connection connection = DriverManager.getConnection(...);
PreparedStatement ps = connection.prepareStatement(...);
ResultSet rs = ps.executeQuery();

With Spring Data JPA:

repository.findAll();

Spring automatically generates SQL queries and handles database operations.

Benefits

  • Less boilerplate code

  • Easy CRUD operations

  • Pagination support

  • Sorting support

  • Query generation

  • Better maintainability


Project Structure

A typical Spring Boot application using JPA follows this structure:

src/main/java
|
├── controller
│   └── EmployeeController.java
|
├── service
│   └── EmployeeService.java
|
├── repository
│   └── EmployeeRepository.java
|
├── entity
│   └── Employee.java
|
└── SpringBootApplication.java

Each layer has a specific responsibility:

LayerResponsibility
    Entity        Maps Java objects to database tables
    Repository        Handles database operations
    Service        Business logic
    Controller        API endpoints

Required Dependencies

Add the following dependencies in your pom.xml.

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <scope>runtime</scope>
    </dependency>

</dependencies>

Purpose of Dependencies

  • spring-boot-starter-web → REST APIs

  • spring-boot-starter-data-jpa → JPA support

  • postgresql → PostgreSQL driver


PostgreSQL Configuration

Configure the database connection in application.properties.

spring.datasource.url=jdbc:postgresql://localhost:5432/companydb
spring.datasource.username=postgres
spring.datasource.password=postgres

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

Property Explanation

PropertyDescription
    datasource.url        PostgreSQL connection URL
    datasource.username        Database username
    datasource.password        Database password
    ddl-auto        Automatically creates or updates tables
    show-sql        Displays SQL queries in console
    format_sql        Formats generated SQL

Creating an Entity Class

An Entity represents a database table.

Let's create an Employee entity.

package com.example.entity;

import jakarta.persistence.*;

@Entity
@Getter
@Setter @Table(name = "employees") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String name; private String department; private Double salary; public Employee() { } public Employee(Long id, String name, String department, Double salary) { this.id = id; this.name = name; this.department = department; this.salary = salary; } }

we can replace @Getter and @Setter annotation with @Data annotation from Lombok


Understanding JPA Annotations

Marks the class as a JPA entity.

@Entity

@Entity
public class Employee {
}

Spring Boot maps this class to a database table.


@Table

Defines the table name.

@Table(name="employees")

If omitted, Hibernate uses the class name.


@Id

Specifies the primary key.

@Id
private Long id;

@GeneratedValue

Automatically generates primary key values.

@GeneratedValue(strategy = GenerationType.IDENTITY)

Common strategies:

StrategyDescription
    AUTO        Default
    IDENTITY        Database auto increment
    SEQUENCE        Uses sequence
    TABLE        Uses table generator

@Column

Customizes column properties.

@Column(nullable=false)
private String name;

Options include:

  • nullable

  • unique

  • length

  • name


How Hibernate Creates Tables

When the application starts, Hibernate generates SQL based on entity definitions.

Example generated table:

CREATE TABLE employees (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    department VARCHAR(255),
    salary NUMERIC
);

This automatic table creation saves development time.


Creating Repository Interface

Repositories handle database operations.

Create:

package com.example.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.entity.Employee;

@Repository
public interface EmployeeRepository
        extends JpaRepository<Employee, Long> {

}

That's it.

No implementation class is required.

Spring automatically provides implementations during runtime.


Understanding JpaRepository

JpaRepository provides several built-in methods.

JpaRepository<Employee, Long>

Where:

  • Employee → Entity class

  • Long → Primary key type


Common Repository Methods

Save Data

repository.save(employee);

Fetch All Records

repository.findAll();

Find By ID

repository.findById(1L);

Delete Record

repository.deleteById(1L);

Count Records

repository.count();

Check Existence

repository.existsById(1L);

These methods are already available without writing SQL queries.


Creating Service Layer

A service layer contains business logic.

@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository repository;

    public Employee saveEmployee(Employee employee) {
        return repository.save(employee);
    }

    public List<Employee> getAllEmployees() {
        return repository.findAll();
    }
}

The service layer acts as a bridge between controller and repository.


Creating REST Controller

Now expose APIs.

@RestController
@RequestMapping("/employees")
public class EmployeeController {

    @Autowired
    private EmployeeService service;

    @PostMapping
    public Employee saveEmployee(
            @RequestBody Employee employee) {

        return service.saveEmployee(employee);
    }

    @GetMapping
    public List<Employee> getEmployees() {
        return service.getAllEmployees();
    }
}

Testing the Application

Start the application.

Insert Employee

POST Request

POST /employees

Request Body:

{
  "name": "Sulochana",
  "department": "IT",
  "salary": 50000
}

Response:

{
  "id": 1,
  "name": "Sulochana",
  "department": "IT",
  "salary": 50000
}

Fetch Employees

GET Request

GET /employees

Response:

[
  {
    "id": 1,
    "name": "Sulochana",
    "department": "IT",
    "salary": 50000
  }
]

Derived Query Methods

One of Spring Data JPA's most powerful features is query generation.

Suppose we want employees by department.

Add:

List<Employee> findByDepartment(String department);

Repository:

public interface EmployeeRepository
extends JpaRepository<Employee, Long> {

    List<Employee> findByDepartment(
            String department);

}

Spring automatically generates SQL.

Usage:

repository.findByDepartment("IT");

No SQL required.


Advantages of Using JPA Repositories

Faster Development

Reduces coding effort significantly.

Cleaner Code

Repository interfaces remain simple and readable.

Automatic SQL Generation

No need to manually write CRUD queries.

Better Maintainability

Changes can be managed centrally.

Production Ready

Used extensively in enterprise applications.


Best Practices

Use Separate Layers

Maintain Controller → Service → Repository architecture.

Keep Entities Simple

Avoid business logic inside entities.

Use DTOs for APIs

Expose DTOs instead of entities in large projects.

Enable SQL Logging During Development

spring.jpa.show-sql=true

Disable it in production.

Use Meaningful Table Names

@Table(name = "employees")

Improves database readability.


Common Mistakes to Avoid

Missing @Entity Annotation

@Entity

Without it, Hibernate will not create the table.

Missing Primary Key

Every entity must have:

@Id

Incorrect Package Structure

Repositories and entities should be under the main package hierarchy.

Wrong Database Credentials

Verify:

spring.datasource.username

spring.datasource.password

Spring Data JPA Interview Questions

1. What is JPA in Spring Boot?

JPA (Java Persistence API) is a Java specification that provides a standard way to map Java objects to relational database tables and perform database operations.

2. What is the difference between JPA and Hibernate?

JPA is a specification, while Hibernate is one of the most popular implementations of the JPA specification. Spring Boot uses Hibernate as the default JPA provider.

3. What is the purpose of the @Entity annotation?

The @Entity annotation marks a Java class as a JPA entity and maps it to a database table. Each entity typically represents a table in the database.

4. What is JpaRepository?

JpaRepository is an interface provided by Spring Data JPA that offers built-in methods for CRUD operations, pagination, sorting, and query execution without writing SQL.

5. Why should we use Spring Data JPA instead of JDBC?

Spring Data JPA reduces boilerplate code, provides automatic query generation, simplifies database access, and improves maintainability compared to traditional JDBC.


Conclusion :

Spring Data JPA simplifies database interactions by allowing developers to map Java objects directly to PostgreSQL tables and perform database operations with minimal code. By using Entity classes and Repository interfaces, developers can build scalable, maintainable, and enterprise-ready applications without writing repetitive SQL statements.

In this article, we explored how to create JPA entities, configure PostgreSQL, create repository interfaces, understand common JPA annotations, and leverage Spring Data JPA for efficient data access.

With these concepts in place, you are now ready to design robust persistence layers for your Spring Boot applications and take advantage of the powerful features offered by Spring Data JPA.

What's Next?

In the next article, we will explore JPA Relationships in Spring Boot, including @OneToOne, @OneToMany, and @ManyToOne mappings. Understanding these relationships is essential for modeling real-world database scenarios and building enterprise-grade applications.

Comments

Popular posts from this blog

React Basics – How to Create Component

How to Build REST API using Spring Boot (Step-by-Step Guide)

Spring Boot @RequestParam Annotation Explained with Real-Time Examples