Lesson 6 of 646 minModule progress 0%

Module 16: Database Integration and Persistence

Mini-Project: Persistence-Backed CRUD Service

Build a CRUD service that turns persistence concepts into a small but realistic application. The goal is to combine validation, repository boundaries, transactions, and response shaping so the service remains maintainable when requirements grow.

Author

Java Learner Editorial Team

Reviewer

Technical review by Java Learner

Last reviewed

2026-04-17

Java version

Java 25 LTS

How this lesson was prepared: AI-assisted draft, manually expanded into a full lesson guide, and checked against current official Java, Spring, testing, and delivery documentation.

Learning goals

  • Design a small persistence-backed service with clear layers
  • Apply transaction, validation, and mapping choices intentionally
  • Practice turning raw data operations into a maintainable backend feature

Before you start

  • You are comfortable with classes, exceptions, and writing small multi-class Java programs

Lesson roadmap: Start with the mental model, then follow the design choices, common pitfalls, and the practical workflow you should apply in a real project.

Project goal: Build a simple service for users, tasks, books, or inventory items with create, read, update, and delete operations.

What to practice: Table or entity design, repository boundaries, validation, transaction use, and clean failure handling.

Suggested structure: Keep request or command validation separate from raw database code so responsibilities stay readable.

Success check: The service should be easy to test and should clearly separate persistence logic from business logic.

Project scope: Choose one simple domain such as books, products, or tickets. Implement create, read, update, and delete flows with one consistent validation and error-handling strategy.

Suggested architecture: DTOs define the external shape, services enforce business rules, repositories handle persistence, and one mapper layer translates between entities and DTOs.

Milestone plan: Start with read-only endpoints or commands, add create, then update, then delete, then validation and transaction polishing. Incremental delivery reduces the chance of a tangled first draft.

Professional finish: Add pagination for list operations, clear error messages for missing records and validation failures, and at least one test path for both successful and failing operations.

How to study this module: Keep a simple domain in mind, such as users, orders, or tasks. It is easier to understand JDBC, transactions, and ORM mapping when every SQL statement serves a clear business action.

Code review mindset: Database code is not only about “does it work.” Reviewers also look for resource safety, transaction boundaries, predictable query counts, and whether the persistence layer leaks too much SQL detail into higher layers.

Production habit: Measure query behavior early. Slow queries, long transactions, and leaked connections usually hurt real systems more than syntax mistakes do.

Runnable examples

A repository boundary keeps persistence localized

interface UserRepository {
    User findById(long id);
    void save(User user);
}

Expected output

A repository interface separates data access from service logic.

A service method should enforce business rules before saving

public ProductDto create(CreateProductRequest request) {
    if (request.name().isBlank()) {
        throw new IllegalArgumentException("name is required");
    }
    return repository.save(mapper.toEntity(request));
}

Expected output

The service layer protects the business rule instead of pushing every concern into the controller or repository.

Common mistakes

Letting the controller own validation, mapping, and persistence decisions

Use the controller as a thin boundary and keep business decisions in the service layer.

Building CRUD only for the happy path

Decide what happens for duplicates, missing IDs, invalid input, and transaction failure before you call the service “done.”

Mini exercise

Write the first milestone plan for your CRUD service. List the entity, the DTOs, the service methods, the repository methods, and one validation rule you will implement before adding any extras.

Summary

  • CRUD projects are where persistence design becomes concrete.
  • Clear separation between data access and business rules improves maintainability.
  • Validation and transaction boundaries belong in the design from the start.
  • A CRUD project becomes professional when boundaries, validation, and failure handling are clear.
  • Project sequencing matters: finish thin slices first, then add polish.

Next step

The next module builds on this with Spring Boot so services can expose HTTP endpoints cleanly.

Sources used

Advertisement

Lesson check

Why is a repository or DAO boundary useful?

Next lesson →