LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 1020 min read

NoSQL & Caching Dependencies

A catalog of the Spring Boot starters for MongoDB, Redis, and Elasticsearch, plus the caching starters that sit in front of any slow data source.

Introduction

Not every application fits neatly into rows and columns. Some data is naturally document-shaped (a user profile with nested addresses), some is best kept as fast, disposable key-value pairs (a session or a rate-limit counter), and some needs to be searched by relevance rather than exact match (a product catalog search bar). This lesson covers the Spring Boot starters that plug into each of those shapes, plus the caching layer that speeds up repeated reads regardless of where the data lives.

What You Will Learn
  • How to store and query documents with spring-boot-starter-data-mongodb.
  • How to use Redis for key-value storage and session state with spring-boot-starter-data-redis.
  • How to wire up full-text search with spring-boot-starter-data-elasticsearch.
  • How to add a caching layer with spring-boot-starter-cache and Caffeine.

MongoDB: Document Storage

MongoDB stores data as JSON-like documents instead of table rows. It is a good fit when your objects are naturally nested (an order with embedded line items) or when the schema changes often between records. spring-boot-starter-data-mongodb gives you a MongoTemplate, repository support via MongoRepository, and auto-configuration for the Mongo driver — you only need to supply a connection URI.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
spring.data.mongodb.uri=mongodb://localhost:27017/shopdb
@Document(collection = "products")
public class Product {
@Id
private String id;
private String name;
private double price;
private List<String> tags;
// constructors, getters, setters
}
public interface ProductRepository extends MongoRepository<Product, String> {
List<Product> findByTagsContaining(String tag);
}
@Service
public class ProductService {
private final ProductRepository repository;
public ProductService(ProductRepository repository) {
this.repository = repository;
}
public Product save(Product product) {
return repository.save(product);
}
public List<Product> findByTag(String tag) {
return repository.findByTagsContaining(tag);
}
}
Behavior

Click Run to see what this code prints.

Redis: Key-Value & Sessions

Redis is an in-memory key-value store, commonly used for caching, session storage, rate limiting, and pub/sub messaging. spring-boot-starter-data-redis brings in Lettuce (the default Redis client) and auto-configures a RedisTemplate you can inject anywhere you need fast, ephemeral storage.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
spring.data.redis.host=localhost
spring.data.redis.port=6379
@Service
public class SessionTokenService {
private final RedisTemplate<String, String> redisTemplate;
public SessionTokenService(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void storeToken(String sessionId, String token) {
redisTemplate.opsForValue()
.set("session:" + sessionId, token, Duration.ofMinutes(30));
}
public String getToken(String sessionId) {
return redisTemplate.opsForValue().get("session:" + sessionId);
}
}
Session Storage at Scale

For a full HTTP session backed by Redis instead of just raw key-value operations, add spring-session-data-redis alongside this starter — it replaces the in-memory HttpSession with one persisted in Redis, so sessions survive app restarts and work across multiple instances behind a load balancer.

Elasticsearch: Full-Text Search

A SQL LIKE query does not scale for search — it cannot rank results by relevance, handle typos, or search across multiple fields efficiently. Elasticsearch is a search engine built for exactly that. spring-boot-starter-data-elasticsearch gives you an ElasticsearchRepository interface backed by the Elasticsearch REST client.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
@Document(indexName = "articles")
public class Article {
@Id
private String id;
@Field(type = FieldType.Text)
private String title;
@Field(type = FieldType.Text)
private String body;
}
public interface ArticleRepository extends ElasticsearchRepository<Article, String> {
List<Article> findByTitleContaining(String keyword);
}
Use Case

Click Run to see what this code prints.

Caching with Caffeine

Caching stores the result of an expensive call (a slow query, a remote API call) so the next request for the same input can skip straight to the answer. spring-boot-starter-cache turns on Spring's caching abstraction (the @Cacheable/@CacheEvict annotations), and com.github.ben-manes.caffeine:caffeine supplies a fast, in-memory cache implementation to back it.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager manager = new CaffeineCacheManager("products");
manager.setCaffeine(Caffeine.newBuilder()
.maximumSize(500)
.expireAfterWrite(Duration.ofMinutes(10)));
return manager;
}
}
@Service
public class ProductService {
@Cacheable("products")
public Product findById(String id) {
System.out.println("Hitting the database for " + id);
return repository.findById(id).orElseThrow();
}
@CacheEvict(value = "products", key = "#id")
public void updateProduct(String id, Product product) {
repository.save(product);
}
}
Behavior

Click Run to see what this code prints.

Comparison Table

DependencyData ShapeBest For
spring-boot-starter-data-mongodbJSON-like documentsFlexible, nested schemas
spring-boot-starter-data-redisKey-value pairsSessions, caching, counters
spring-boot-starter-data-elasticsearchIndexed text documentsFull-text and fuzzy search
spring-boot-starter-cache + caffeineIn-memory cache entriesSpeeding up repeated method calls

Common Mistakes

Avoid These Mistakes
  • Using Redis as a system of record instead of a cache — data in Redis can be evicted or lost, so it should never be the only copy of important data.
  • Forgetting @EnableCaching, which silently makes @Cacheable a no-op.
  • Reaching for Elasticsearch when a database index and a LIKE query would be plenty fast enough for the actual data volume.

Frequently Asked Questions

It is the easiest path — docker run mongo, docker run redis, and docker run elasticsearch each get you a local instance in seconds without installing anything natively.

Yes, and it is a very common combination — MongoDB as the source of truth, Redis as a fast cache in front of it.

No. Spring's cache abstraction also works with Redis, EhCache, and others — Caffeine is simply the most common choice for a local, in-process cache.

Summary

MongoDB, Redis, and Elasticsearch each solve a different data-shape problem, and Spring Boot's caching starter lets you speed up any of them (or a plain SQL database) with a single annotation. Next, we secure the endpoints sitting in front of all this data.

Next Lesson →

Security Dependencies