Spring Boot

Capstone – Article 3: User Repository & Basic CRUD (Expense Tracker)

By Utility Zone · 2026-01-27T18:31:33.590865

1. Introduction

Now that the database and User entity are ready, it’s time to actually work with data.

In this article, you will:

  • Create a JPA repository
  • Perform basic CRUD operations
  • Verify data persistence via H2 console
  • Follow proper layering (Controller → Service → Repository)

This is the backbone of every backend application.


2. Why Repository Layer?

The repository layer:

  • Handles all database operations
  • Hides JPA/Hibernate complexity
  • Keeps service and controller clean

Spring Data JPA generates implementations automatically.


3. Creating UserRepository

3.1 Create Repository Package

Create package:

com.example.expensetracker.repository

3.2 Create UserRepository Interface

package com.example.expensetracker.repository;

import com.example.expensetracker.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {

    Optional<User> findByEmail(String email);
}

Why findByEmail?

  • Email is unique
  • Used for login later
  • Common real-world pattern

4. Creating UserService

4.1 Create Service Package

Create package:

com.example.expensetracker.service

4.2 Create UserService Class

package com.example.expensetracker.service;

import com.example.expensetracker.entity.User;
import com.example.expensetracker.repository.UserRepository;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User createUser(User user) {
        return userRepository.save(user);
    }

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    public User getUserById(Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("User not found"));
    }
}

Note:

  • No controller logic here
  • Pure business/data logic

5. Creating UserController

5.1 Create Controller Package

Create package:

com.example.expensetracker.controller

5.2 Create UserController

package com.example.expensetracker.controller;

import com.example.expensetracker.entity.User;
import com.example.expensetracker.service.UserService;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user);
    }

    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}

6. Testing CRUD Operations

6.1 Create User (POST)

Endpoint:

POST /users

Body:

{
  "name": "Bharat",
  "email": "bharat@email.com",
  "password": "test123",
  "role": "USER"
}

6.2 Get All Users (GET)

GET /users

6.3 Get User by ID (GET)

GET /users/1

7. Verify in H2 Console

Open:

/h2-console

Run:

SELECT * FROM USERS;

You should see the inserted data.


8. Important Design Notes

✔ Controller does NOT talk to repository
✔ Service handles business logic
✔ Repository handles DB operations

This separation is interview-critical.


9. Common Beginner Mistakes

❌ Direct repository access in controller
❌ Returning Optional to API
❌ No service layer
❌ Hardcoding IDs


10. Git Commit (Important)

Commit your changes:

git add .
git commit -m "Add User repository, service, and basic CRUD APIs"

11. What You Should Have Now

At this point:

  • You can create users
  • Fetch users
  • Persist data
  • Follow clean layering

This is a major real-world milestone.


12. What’s Next?

➡ Capstone – Article 4: DTOs, Validation & API Contracts

  • Request/response DTOs
  • Validation annotations
  • Cleaner APIs

Type Next when you’re ready 🚀