Repositories & @Repository
The repository pattern gives you a collection-like abstraction over persistence, and @Repository marks that data-access bean — the clean boundary between your business logic and the data store.
Learn Repositories & @Repository in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Before You Start
You should understand the service layer and interfaces , since a repository is fundamentally an interface that services depend on.
What You'll Learn
The Big Idea — A Librarian at the Counter
💡 Analogy: A repository is like a librarian . You ask "find book #42" or "store this book", and the librarian handles it — you never see whether the books are on shelves, in a basement archive, or scanned into a database. The librarian is the single counter (boundary) between you and the storage. Swap the basement for a digital archive and your request doesn't change at all.
That counter is the persistence boundary: callers stay blissfully ignorant of how storage works.
1️⃣ The Repository Pattern
Define an interface with collection-like operations — save , findById , findAll , deleteById . Callers depend on this abstraction, never on the storage details behind it.
2️⃣ The @Repository Bean
@Repository registers the data-access bean and, crucially, enables persistence-exception translation into Spring's unchecked DataAccessException hierarchy.
3️⃣ Services Depend on Repositories
The service injects the repository interface and uses it. Business logic stays persistence-ignorant — and you can inject an in-memory fake in tests.
4️⃣ The Pattern, Made Concrete
Here is the whole pattern in plain Java with real output: an interface, an in-memory implementation, and callers that could swap to a DB-backed version without changing.
🧠 Quick Recall
Answer: a collection-like interface over persistence, hiding how data is stored.
Answer: persistence-exception translation into Spring's unchecked DataAccessException hierarchy.
Answer: the service layer — it uses the repository to read and write data.
Common Errors
- ❌ Data access in the controller/service body. Leaks persistence. Fix: hide it behind a repository.
- ❌ Depending on the implementation, not the interface. Blocks swapping. Fix: depend on the repository interface.
- ❌ Web concerns in the repository. e.g. status codes. Fix: keep it persistence-only.
- ❌ Catching technology-specific exceptions. Couples you to the store. Fix: rely on DataAccessException.
- ❌ Treating the repository as a place for business rules. Fix: keep rules in the service.
Pro Tips
- 💡 Return Optional from finders to express "may not exist" cleanly.
- 💡 Keep repositories thin — persistence operations only, no business rules.
- 💡 Use an in-memory repository in tests for fast, DB-free unit tests.
- 💡 Let Spring Data generate repositories (next lesson) once you understand the pattern.
📋 Quick Reference
Concept
Syntax / idea
Note
pattern
collection-like API
Over persistence
data bean
@Repository
Persistence layer
stereotype of
@Component
+ exception translation
errors
DataAccessException
Unchecked, agnostic
boundary
logic ⟷ data store
Persistence ignorance
depends on it
the service layer
Via the interface
📚 Resources / Keep Learning
- 📘 DAO Support & Exception Translation — Spring docs
- 📗 Working with Spring Data Repositories — docs
- 📗 Accessing Data with JPA — spring.io guide
❓ Frequently Asked Questions
🎉 Lesson Complete!
You now understand the repository pattern as a collection-like abstraction over persistence, what @Repository marks and the exception translation it adds, and why the repository is the clean boundary between business logic and the data store.
Next up: Spring Data JPA Basics — letting Spring generate the repository implementation for you.
Practice quiz
What does the repository pattern provide?
- A collection-like abstraction over data access / persistence
- A UI framework
- A logging system
- A thread pool
Answer: A collection-like abstraction over data access / persistence. The repository pattern abstracts persistence behind a collection-like interface, hiding how data is actually stored.
What does @Repository mark?
- A controller
- A bean in the persistence (data access) layer
- A config class
- A scheduled task
Answer: A bean in the persistence (data access) layer. @Repository is a stereotype of @Component marking a data-access bean in the persistence layer.
Besides registering a bean, @Repository enables...
- HTTP routing
- JSON serialisation
- persistence-exception translation into Spring's DataAccessException
- transaction creation
Answer: persistence-exception translation into Spring's DataAccessException. @Repository triggers exception translation, converting provider-specific exceptions into Spring's unchecked DataAccessException hierarchy.
The repository is the boundary between...
- the controller and the view
- business logic and the data store
- Java and the JVM
- the client and the network
Answer: business logic and the data store. Repositories form the persistence boundary, separating business logic from the details of the underlying data store.
Which layer typically depends on a repository?
- The controller directly, always
- application.properties
- The main method
- The service layer
Answer: The service layer. Services depend on repositories to read and write data, keeping persistence behind that boundary.
A key benefit of programming to a repository interface is...
- faster compilation
- swapping the implementation (e.g. in-memory for tests) without changing callers
- smaller jars
- automatic UI
Answer: swapping the implementation (e.g. in-memory for tests) without changing callers. Coding against an interface lets you substitute an in-memory fake in tests or change the storage technology freely.
Is @Repository required for component scanning to find the bean?
- No — but it documents intent and adds exception translation
- Yes, scanning ignores @Component
- Only in tests
- Only for JPA
Answer: No — but it documents intent and adds exception translation. Any @Component is scanned; @Repository additionally conveys the data-access role and enables exception translation.
What does 'persistence ignorance' in callers mean?
- Callers know the SQL dialect
- Callers disable persistence
- Callers use the repository without knowing the storage mechanism
- Callers cache everything
Answer: Callers use the repository without knowing the storage mechanism. Callers depend on the repository abstraction and stay ignorant of whether it's JDBC, JPA, or in-memory.
Which is NOT a responsibility of a repository?
- Saving entities
- Finding entities by id
- Defining HTTP status codes
- Deleting entities
Answer: Defining HTTP status codes. HTTP status codes are a web-layer concern; a repository handles persistence operations only.
Spring's DataAccessException hierarchy is...
- checked exceptions you must catch
- unchecked (runtime) and storage-technology-agnostic
- only for JDBC
- deprecated
Answer: unchecked (runtime) and storage-technology-agnostic. DataAccessException is an unchecked, consistent abstraction over different persistence technologies' exceptions.
Continue this course
- Previous: The Service Layer
- Next: Spring Data JPA Basics