How should I use JpaRepository.findOne with SpringBoot?
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
In Spring Data JPA 2.0+, findOne() was replaced by findById(), which returns Optional<T> instead of the entity directly. If you are using a recent version of Spring Boot (2.x or 3.x), use findById(id) and handle the Optional. The old findOne(ID id) method no longer exists on CrudRepository. If you need to find by a non-ID field, use findOne(Example<T>) from QueryByExampleExecutor or define a custom query method.
The Change: findOne to findById
The change was made to eliminate null-pointer bugs — Optional forces you to handle the "not found" case explicitly.
Using findById (Recommended)
Repository Interface
Handling Optional Results
findOne with Example (Query by Example)
JpaRepository extends QueryByExampleExecutor, which has findOne(Example<T>):
This version of findOne takes an Example parameter, not an ID. It finds a single entity matching the provided probe values.
Custom Query Methods
For finding by non-ID fields, define custom repository methods:
getReferenceById (Lazy Loading)
If you only need a reference (proxy) without hitting the database:
Use getReferenceById when you need to set a foreign key without loading the full entity:
Controller Example
Migration from findOne to findById
Common Pitfalls
- Calling
findOne(id)on JpaRepository: ThefindOne(ID)method no longer exists in Spring Data JPA 2.0+. It was replaced byfindById(ID)which returnsOptional<T>. If your code callsfindOne(1L), it will not compile. - Calling
.get()without checkingisPresent():Optional.get()throwsNoSuchElementExceptionif the Optional is empty. Always useorElseThrow(),orElse(), orifPresent()instead of raw.get(). - Confusing
findOne(Example)withfindOne(ID):findOne(Example<T>)fromQueryByExampleExecutorstill exists and takes a probe object, not an ID. It throwsIncorrectResultSizeDataAccessExceptionif more than one result matches. - Using
orElse()with a method call:orElse(createUser())always callscreateUser(), even when the Optional has a value. UseorElseGet(() -> createUser())for lazy evaluation. - Not using
getReferenceByIdfor associations: Loading a full entity withfindByIdjust to set a foreign key wastes a database query. UsegetReferenceByIdto get a proxy reference without querying.
Summary
- Use
findById(id)instead of the removedfindOne(id)— it returnsOptional<T> - Handle the Optional with
orElseThrow(),orElse(),map(), orifPresent() - Use
findOne(Example<T>)to query by non-ID fields with Query by Example - Define custom repository methods (
findByEmail) for typed, compile-safe queries - Use
getReferenceById(id)when you only need a proxy reference, not the full entity
Related reading
- How some NoSQL DB (like MongoDB) can handle all of C and P in CAP theorem?
- How store an object in Dynamodb?
- How the hash function by partitioner in Cassandra is decided for a particular data set to ensure even distribution of data across multiple cluster?
- How to access a preexisting collection with Mongoose?
- How should I use servlets and Ajax?
- How Spring Boot Application works internally?
- How to access mysql outside my kubernetes cluster?
- How to access remote server with local phpMyAdmin client?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.