Spring Data MongoDB is part of the Spring Data family. It provides an easy way to interact with MongoDB databases using Spring Boot or Spring Framework. Instead of manually writing a lot of boilerplate code for queries, connections, and data conversions, Spring Data MongoDB automates and simplifies most of that
Here’s how it works at a high level:
1. MongoTemplate (Lower-level API)
MongoTemplate
is the core class that handles interactions with MongoDB.- It provides methods like
save()
,find()
,findOne()
,remove()
, etc. - You can manually construct queries if you need full control.
Example:
@Autowired
private MongoTemplate mongoTemplate;
public List<User> getAllUsers() {
return mongoTemplate.findAll(User.class);
}
2. MongoRepository (Higher-level abstraction)
- If you don’t want to manually write queries, you can create a Repository interface that extends
MongoRepository
. - Spring will automatically generate implementations for common database operations.
Example:
public interface UserRepository extends MongoRepository<User, String> {
List<User> findByName(String name);
}
Usage:
@Autowired
private UserRepository userRepository;
public List<User> findUsersByName(String name) {
return userRepository.findByName(name);
}
You don’t need to implement anything — just declare the method signatures, and Spring generates the queries based on method names (this is called Query Method Derivation).
3. Domain Model (Entity Classes)
- You create simple Java classes annotated with
@Document
(to mark them as MongoDB documents). - Fields can be annotated with
@Id
(primary key) and other annotations like@Field
.
Example:
@Document(collection = "users")
public class User {
@Id
private String id;
private String name;
private int age;
// getters and setters
}
4. Configuration
- In Spring Boot, configuration is mostly automatic if you include the right dependencies (
spring-boot-starter-data-mongodb
). - You just set a few properties in
application.properties
orapplication.yml
:
spring.data.mongodb.uri=mongodb://localhost:27017/mydatabase
5. Advanced Features
- Custom queries with
@Query
annotations. - Aggregation pipelines for complex data transformations.
- Validation with Java Bean Validation (e.g.,
@NotNull
). - Reactive programming (with Spring WebFlux) if you want non-blocking MongoDB operations using
ReactiveMongoRepository
.
Summary Diagram (quick mental picture):
Your Code (UserRepository, User class)
↓
Spring Data MongoDB (automatic query building, templates)
↓
MongoDB Java Driver
↓
MongoDB Server
Now, let’s dive into how Spring Data MongoDB parses repository interfaces and generates code behind the scenes.
🔥 How Spring Mongo Repositories Work Internally
1. At startup: Spring scans repository interfaces
When your Spring Boot app starts, Spring looks for interfaces that extend a base interface like:
MongoRepository<User, String>
It finds these interfaces because of:
- Classpath scanning (
@EnableMongoRepositories
or auto-configuration). - Marker interfaces and packages.
Spring doesn’t look for concrete classes — it looks for interfaces and automatically generates implementations.
2. Spring creates proxy instances
- Spring uses dynamic proxies or CGLIB proxies to create runtime classes that “implement” your repository interface.
- These proxies intercept your method calls and handle them dynamically.
The real class you talk to is something like:
SimpleMongoRepository (for standard methods)
CustomMongoRepositoryImpl (for custom implementations)
3. Spring parses method names
When you declare methods like:
List<User> findByNameAndAgeGreaterThan(String name, int age);
Spring parses the method name based on a predefined naming convention:
findBy
→ means a find query.NameAndAgeGreaterThan
→ means where name = ? AND age > ?.
The parsing engine tokenizes the method name, maps it to MongoDB fields, and understands operations like:
And
,Or
,GreaterThan
,LessThan
,IsNull
, etc.
Spring uses internal classes like:
PartTree
QueryMethod
MongoQueryCreator
Example:findByNameAndAgeGreaterThan
→ parsed into a MongoDB query document:
{ "name": "John", "age": { "$gt": 25 } }
4. Spring generates the MongoDB query
Once Spring has the parsed structure, it:
- Builds a
Query
object (fromorg.springframework.data.mongodb.core.query.Query
). - Converts your method arguments into query parameters.
- Sends the query to MongoTemplate internally.
Example (behind the scenes):
Query query = new Query();
query.addCriteria(Criteria.where("name").is(name).and("age").gt(age));
mongoTemplate.find(query, User.class);
You never see this code, but that’s what’s happening inside.
5. Custom Queries (@Query)
If you want, you can override the method parsing by using @Query
:
@Query("{ 'name' : ?0, 'age' : { $gt : ?1 } }")
List<User> customFind(String name, int age);
In this case, Spring directly uses your query string instead of trying to parse the method name.
🔥 Quick Visual Summary:
Your Repository Interface
↓
Spring Boot scans interfaces
↓
Proxy instance created (SimpleMongoRepository)
↓
Method call intercepted
↓
Method name parsed → Query object built
↓
MongoTemplate used to run query
↓
Result returned
✨ Important Internals:
Feature | Internal class |
---|---|
Parsing method name | PartTree , Part |
Building Mongo queries | MongoQueryCreator , Criteria |
Executing query | MongoTemplate |
Creating repository proxy | RepositoryFactorySupport , MongoRepositoryFactory |
⚡ Bonus Tip:
If you want to see the generated queries at runtime, add this to application.properties
:
logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG
Spring will log actual MongoDB queries to the console!