### Build the project Source: https://github.com/spring-projects/spring-data-redis/blob/main/README.adoc Performs a clean install of the project using the Maven wrapper. ```bash $ ./mvnw clean install ``` -------------------------------- ### Implement Query by Example with PersonRepository Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/query-by-example.adoc Demonstrates how to extend ListQueryByExampleExecutor to enable QBE functionality in a Spring Data Redis repository. The service class shows the usage of Example.of(probe) to execute queries against the repository. ```java interface PersonRepository extends ListQueryByExampleExecutor { } class PersonService { @Autowired PersonRepository personRepository; List findPeople(Person probe) { return personRepository.findAll(Example.of(probe)); } } ``` -------------------------------- ### Spring Data Redis Hello World Application (Java) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/getting-started.adoc This snippet demonstrates a basic 'Hello World' application for Spring Data Redis. It shows how to create and use RedisTemplate or ReactiveRedisTemplate with a RedisConnectionFactory to store and retrieve values. It requires a running Redis server (version 2.6 or above) and integration with Lettuce or Jedis. ```java package com.example.redis; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.redis.core.RedisTemplate; @SpringBootApplication public class RedisApplication implements CommandLineRunner { @Autowired private RedisTemplate redisTemplate; public static void main(String[] args) { SpringApplication.run(RedisApplication.class, args); } @Override public void run(String... args) throws Exception { // Store a value redisTemplate.opsForValue().set("myKey", "Hello Redis!"); // Retrieve the value String value = redisTemplate.opsForValue().get("myKey"); System.out.println("Retrieved value: " + value); } } ``` ```java package com.example.redis; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; import org.springframework.data.redis.core.ReactiveRedisTemplate; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class ReactiveRedisConfig { @Bean public ReactiveRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) { RedisSerializationContext.SerializationContext serializationContext = RedisSerializationContext.newSerializationContext(new StringRedisSerializer()) .hashKey(new StringRedisSerializer()) .hashValue(new StringRedisSerializer()) .build(); return new ReactiveRedisTemplate<>(factory, serializationContext); } } ``` -------------------------------- ### Use Deque with Redis in Java Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/support-classes.adoc Demonstrates using a Redis-backed Deque in Java. This example shows how to interact with a Deque interface, abstracting the underlying Redis storage. ```java public class AnotherExample { // injected private Deque queue; public void addTag(String tag) { queue.push(tag); } } ``` -------------------------------- ### Programmatic Index Setup with RedisMappingContext (Java) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/indexes.adoc Demonstrates a programmatic approach to configuring secondary indexes by defining a `RedisMappingContext` bean. This method offers fine-grained control over index definitions. ```java @Configuration @EnableRedisRepositories public class ApplicationConfig { //... RedisConnectionFactory and RedisTemplate Bean definitions omitted @Bean public RedisMappingContext keyValueMappingContext() { return new RedisMappingContext( new MappingConfiguration( new KeyspaceConfiguration(), new MyIndexConfiguration())); } public static class MyIndexConfiguration extends IndexConfiguration { @Override protected Iterable initialConfiguration() { return Collections.singleton(new SimpleIndexDefinition("people", "firstname")); } } } ``` -------------------------------- ### Configure RedisList Bean in Java Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/support-classes.adoc Configures a RedisList bean using Java. This example demonstrates how to create a DefaultRedisList instance, which wraps Redis key incrementation and provides list/queue/deque functionalities. ```java @Configuration class MyConfig { // … @Bean RedisList stringRedisTemplate(RedisTemplate redisTemplate) { return new DefaultRedisList<>(template, "queue-key"); } } ``` -------------------------------- ### Configure RedisList Bean in XML Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/support-classes.adoc Configures a RedisList bean using XML. This example shows the equivalent XML configuration for creating a DefaultRedisList instance, abstracting Redis operations. ```xml ``` -------------------------------- ### Configure RedisCacheManager with Customizations Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-cache.adoc This example shows how to build a RedisCacheManager with advanced configurations. It allows setting default cache configurations, enabling transaction awareness, and defining initial cache configurations with specific settings like disabling null value caching. ```java RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory) .cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()) .transactionAware() .withInitialCacheConfigurations(Collections.singletonMap("predefined", RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues())) .build(); ``` -------------------------------- ### Configure MessageListenerAdapter Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pubsub-receiving.adoc Configures the MessageListenerAdapter to bridge a POJO delegate with the RedisMessageListenerContainer. This setup enables automatic message serialization and method invocation. ```java @Configuration class MyConfig { @Bean DefaultMessageDelegate listener() { return new DefaultMessageDelegate(); } @Bean MessageListenerAdapter messageListenerAdapter(DefaultMessageDelegate listener) { return new MessageListenerAdapter(listener, "handleMessage"); } @Bean RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory, MessageListenerAdapter listener) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.addMessageListener(listener, ChannelTopic.of("chatroom")); return container; } } ``` ```xml ``` -------------------------------- ### Default Object-to-Hash Mapping Example (Text) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/mapping.adoc Illustrates the default mapping of a Person object to a Redis Hash structure, showing how simple properties, complex types, and nested properties are represented. ```text _class = org.example.Person <1> id = e2c7dcee-b8cd-4424-883e-736ce564363e firstname = rand <2> lastname = al’thor address.city = emond's field <3> address.country = andor ``` -------------------------------- ### Redis Commands for Map and List Property Indexing (Text) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/indexes.adoc Provides examples of Redis commands generated for indexing map keys, nested map properties, and list properties within the 'Person' entity, demonstrating the structure of these indexes. ```text SADD people:attributes.map-key:map-value e2c7dcee-b8cd-4424-883e-736ce564363e SADD people:relatives.map-key.firstname:tam e2c7dcee-b8cd-4424-883e-736ce564363e SADD people:addresses.city:tear e2c7dcee-b8cd-4424-883e-736ce564363e ``` -------------------------------- ### Set Static Cache Key Prefix Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-cache.adoc This example demonstrates how to set a static prefix for all cache keys managed by RedisCacheConfiguration. This custom prefix is prepended to the cache name and the actual key. ```java // static key prefix RedisCacheConfiguration.defaultCacheConfig().prefixCacheNameWith("(͡° ᴥ ͡°)"); ``` -------------------------------- ### Programmatically Configure Redis Keyspaces Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/keyspaces.adoc This approach involves manually defining a RedisMappingContext bean to inject a custom configuration. It provides more granular control over the mapping configuration compared to annotation-based setup. ```java @Configuration @EnableRedisRepositories public class ApplicationConfig { //... RedisConnectionFactory and RedisTemplate Bean definitions omitted @Bean public RedisMappingContext keyValueMappingContext() { return new RedisMappingContext( new MappingConfiguration(new IndexConfiguration(), new MyKeyspaceConfiguration())); } public static class MyKeyspaceConfiguration extends KeyspaceConfiguration { @Override protected Iterable initialConfiguration() { return Collections.singleton(new KeyspaceSettings(Person.class, "people")); } } } ``` -------------------------------- ### Configure RedisCacheManager with Default Settings Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-cache.adoc This snippet demonstrates the basic setup of a RedisCacheManager using a RedisConnectionFactory. It leverages the default configuration provided by Spring Data Redis to integrate Redis as a cache. ```java @Bean public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) { return RedisCacheManager.create(connectionFactory); } ``` -------------------------------- ### Configure Redis Cluster Connection with Lettuce Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/connection-modes.adoc Demonstrates how to define a configuration properties class to hold cluster nodes and a Spring configuration class to instantiate a LettuceConnectionFactory. This setup allows for type-safe management of Redis cluster nodes via application properties. ```java @Component @ConfigurationProperties(prefix = "spring.redis.cluster") public class ClusterConfigurationProperties { /* * spring.redis.cluster.nodes[0] = 127.0.0.1:7379 * spring.redis.cluster.nodes[1] = 127.0.0.1:7380 * ... */ List nodes; /** * Get initial collection of known cluster nodes in format {@code host:port}. * * @return */ public List getNodes() { return nodes; } public void setNodes(List nodes) { this.nodes = nodes; } } @Configuration public class AppConfig { /** * Type safe representation of application.properties */ @Autowired ClusterConfigurationProperties clusterProperties; public @Bean RedisConnectionFactory connectionFactory() { return new LettuceConnectionFactory( new RedisClusterConfiguration(clusterProperties.getNodes())); } } ``` -------------------------------- ### Define Domain Models for Jackson Hash Mapping Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/hash-mappers.adoc Example of domain classes used for Jackson-based hash mapping. These classes demonstrate how simple and complex types are structured for serialization into Redis hashes. ```java public class Person { String firstname; String lastname; Address address; Date date; LocalDateTime localDateTime; } public class Address { String city; String country; } ``` -------------------------------- ### Initialize Stream Receiver Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-streams.adoc A basic example of initializing a stream receiver to start consuming messages from the beginning of a stream. ```java Flux> messages = receiver.receive(StreamOffset.fromStart("my-stream")); ``` -------------------------------- ### Build reference documentation Source: https://github.com/spring-projects/spring-data-redis/blob/main/README.adoc Generates the project documentation without running the full test suite. ```bash $ ./mvnw clean install -Pantora ``` -------------------------------- ### Configure and Use RedisTemplate in Java Source: https://github.com/spring-projects/spring-data-redis/blob/main/README.adoc Demonstrates injecting RedisTemplate and specific operation interfaces, along with basic Lettuce connection factory configuration. ```java public class Example { // inject the actual template @Autowired private RedisTemplate redisTemplate; // inject the template as ListOperations // can also inject as Value, Set, ZSet, and HashOperations @Resource(name="redisTemplate") private ListOperations listOps; public void addLink(String userId, URL url) { listOps.leftPush(userId, url.toExternalForm()); // or use template directly redisTemplate.boundListOps(userId).leftPush(url.toExternalForm()); } } @Configuration class ApplicationConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(); } } ``` -------------------------------- ### Run integration tests Source: https://github.com/spring-projects/spring-data-redis/blob/main/README.adoc Executes the full test suite using the project's Makefile. ```bash $ make test ``` -------------------------------- ### Configure Advanced Lettuce Client Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/drivers.adoc Use LettuceClientConfigurationBuilder to set SSL, command timeouts, and shutdown timeouts. ```java @Bean public LettuceConnectionFactory lettuceConnectionFactory() { LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .useSsl().and() .commandTimeout(Duration.ofSeconds(2)) .shutdownTimeout(Duration.ZERO) .build(); return new LettuceConnectionFactory(new RedisStandaloneConfiguration("localhost", 6379), clientConfig); } ``` -------------------------------- ### Configure Lettuce Unix Domain Socket Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/drivers.adoc Create a connection factory using RedisSocketConfiguration for Unix domain sockets. ```java @Configuration class AppConfig { @Bean public LettuceConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(new RedisSocketConfiguration("/var/run/redis.sock")); } } ``` -------------------------------- ### Publishing messages with Imperative API Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pubsub-sending.adoc Demonstrates sending messages using low-level RedisConnection and high-level RedisOperations. ```java // send message through connection RedisConnection connection = … byte[] channel = … byte[] message = … connection.pubSubCommands().publish(channel, message); // send message through RedisOperations RedisOperations operations = … Long numberOfClients = operations.convertAndSend("chatroom", "hello!"); ``` -------------------------------- ### Configure Lettuce Connection Factory Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/drivers.adoc Define a LettuceConnectionFactory bean for a standalone Redis server. ```java @Configuration class AppConfig { @Bean public LettuceConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379)); } } ``` -------------------------------- ### Publishing messages with Reactive API Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pubsub-sending.adoc Demonstrates sending messages using ReactiveRedisConnection and ReactiveRedisOperations. ```java // send message through connection ReactiveRedisConnection connection = … ByteBuffer channel = … ByteBuffer message = … connection.pubSubCommands().publish(channel, message); // send message through ReactiveRedisOperations ReactiveRedisOperations operations = … Mono numberOfClients = operations.convertAndSend("chatroom", "hello!"); ``` -------------------------------- ### Configure RedisTemplate and ReactiveRedisTemplate Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/template.adoc Configures the Redis template beans for both imperative and reactive paradigms. Requires a RedisConnectionFactory to establish connectivity to the Redis server. ```java @Configuration class MyConfig { @Bean LettuceConnectionFactory connectionFactory() { return new LettuceConnectionFactory(); } @Bean RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); return template; } } ``` ```java @Configuration class MyConfig { @Bean LettuceConnectionFactory connectionFactory() { return new LettuceConnectionFactory(); } @Bean ReactiveRedisTemplate ReactiveRedisTemplate(ReactiveRedisConnectionFactory connectionFactory) { return new ReactiveRedisTemplate<>(connectionFactory, RedisSerializationContext.string()); } } ``` ```xml ``` -------------------------------- ### Perform List Operations with RedisTemplate Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/template.adoc Demonstrates pushing items to a Redis list using injected operations. Shows the difference between direct ListOperations injection in imperative mode and reactive operations in reactive mode. ```java public class Example { @Autowired private RedisOperations operations; @Resource(name="redisTemplate") private ListOperations listOps; public void addLink(String userId, URL url) { listOps.leftPush(userId, url.toExternalForm()); } } ``` ```java public class Example { @Autowired private ReactiveRedisOperations operations; public Mono addLink(String userId, URL url) { return operations.opsForList().leftPush(userId, url.toExternalForm()); } } ``` -------------------------------- ### Execute Redis Command with RedisCallback Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/template.adoc Illustrates using the RedisCallback interface to execute commands directly against a RedisConnection. This provides low-level control and allows casting to specific connection types like StringRedisConnection for operations like setting a key-value pair. ```java public void useCallback() { redisOperations.execute(new RedisCallback() { public Object doInRedis(RedisConnection connection) throws DataAccessException { Long size = connection.dbSize(); // Can cast to StringRedisConnection if using a StringRedisTemplate ((StringRedisConnection)connection).set("key", "value"); } }); } ``` -------------------------------- ### Define Redis Entity with Indexing Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/anatomy.adoc Example of a Java class annotated with @RedisHash and field-level indexing annotations. This structure informs the repository on how to map data to Redis hashes and secondary index sets. ```java @RedisHash("people") public class Person { @Id String id; @Indexed String firstname; String lastname; Address hometown; } public class Address { @GeoIndexed Point location; } ``` -------------------------------- ### Add Link to Redis List (Synchronous) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/template.adoc Demonstrates how to add a URL to a Redis list using StringRedisTemplate. It takes a user ID and a URL, and pushes the URL's string representation to the left of the list associated with the user ID. ```java public class Example { @Autowired private StringRedisTemplate redisTemplate; public void addLink(String userId, URL url) { redisTemplate.opsForList().leftPush(userId, url.toExternalForm()); } } ``` -------------------------------- ### Customizing Message Converters (Java) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pubsub-annotated.adoc Shows how to customize message converters for Redis listeners by implementing RedisListenerConfigurer and overriding the configureMessageConverters method. This example adds a String converter with UTF-8 encoding and a JdkSerializationRedisSerializer. ```java @Configuration @EnableRedisListeners public class AppConfig implements RedisListenerConfigurer { @Override public void configureMessageConverters(RedisMessageConverters.Builder builder) { builder.withStringConverter(StandardCharsets.UTF_8) .addCustomConverter(new JdkSerializationRedisSerializer()); } } ``` -------------------------------- ### Retrieve value during Redis transaction Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/transactions.adoc Demonstrates the behavior of a get operation within a Spring Data Redis transaction. Note that values set within the same transaction scope are not visible to this operation, returning null. ```java // returns null as values set within a transaction are not visible template.opsForValue().get("thing1"); ``` -------------------------------- ### Configure Jedis Connection Factory Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/drivers.adoc Define JedisConnectionFactory beans using default or custom standalone configurations. ```java @Configuration class AppConfig { @Bean public JedisConnectionFactory redisConnectionFactory() { return new JedisConnectionFactory(); } } ``` ```java @Configuration class RedisConfiguration { @Bean public JedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("server", 6379); return new JedisConnectionFactory(config); } } ``` -------------------------------- ### Resulting Hash after Map Conversion (Text) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/mapping.adoc Presents the Redis Hash structure after using the custom Map converters. This example shows how a specific property ('ciudad') is directly mapped to a key in the hash. ```text _class = org.example.Person id = e2c7dcee-b8cd-4424-883e-736ce564363e firstname = rand lastname = al’thor ciudad = "emond's field" ``` -------------------------------- ### Configure Redis CDI Producers Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/cdi-integration.adoc Defines CDI producer methods for RedisConnectionFactory and RedisOperations to manage the lifecycle of Redis infrastructure beans. This setup ensures that the necessary connections and templates are available for injection within the CDI container. ```java class RedisOperationsProducer { @Produces RedisConnectionFactory redisConnectionFactory() { LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(new RedisStandaloneConfiguration()); connectionFactory.afterPropertiesSet(); connectionFactory.start(); return connectionFactory; } void disposeRedisConnectionFactory(@Disposes RedisConnectionFactory redisConnectionFactory) throws Exception { if (redisConnectionFactory instanceof DisposableBean) { ((DisposableBean) redisConnectionFactory).destroy(); } } @Produces @ApplicationScoped RedisOperations redisOperationsProducer(RedisConnectionFactory redisConnectionFactory) { RedisTemplate template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); template.afterPropertiesSet(); return template; } } ``` -------------------------------- ### RedisTemplate Supported Commands Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/appendix.adoc A comprehensive list of Redis commands that are supported by the RedisTemplate implementation. ```APIDOC ## RedisTemplate Supported Commands ### Description This list outlines the Redis commands that are natively supported by the `RedisTemplate` class in Spring Data Redis. ### Supported Commands The following commands are supported: - APPEND, AUTH, BGREWRITEAOF, BGSAVE, BITCOUNT, BITFIELD, BITOP, BLPOP, BRPOP, BRPOPLPUSH - CLIENT KILL, CLIENT GETNAME, CLIENT LIST, CLIENT SETNAME - CONFIG GET, CONFIG RESETSTAT, CONFIG SET - DBSIZE, DECR, DECRBY, DEL, DISCARD, DUMP, ECHO, EVAL, EVALSHA, EXEC, EXISTS, EXPIRE, EXPIREAT - FLUSHALL, FLUSHDB - GEOADD, GEODIST, GEOHASH, GEOPOS, GEORADIUS, GEORADIUSBYMEMBER, GEOSEARCH, GEOSEARCHSTORE - GET, GETBIT, GETRANGE, GETSET - HDEL, HEXISTS, HEXPIRE, HEXPIREAT, HPEXPIRE, HPEXPIREAT, HPERSIST, HTTL, HPTTL, HGET, HGETALL, HINCRBY, HINCRBYFLOAT, HKEYS, HLEN, HMGET, HMSET, HSCAN, HSET, HSETNX, HVALS - INCR, INCRBY, INCRBYFLOAT, INFO, KEYS, LASTSAVE, LINDEX, LINSERT, LLEN, LPOP, LPUSH, LPUSHX, LRANGE, LREM, LSET, LTRIM - MGET, MOVE, MSET, MSETNX, MULTI, PERSIST, PEXIPRE, PEXPIREAT, PFADD, PFCOUNT, PFMERGE, PING, PSETEX, PSUBSCRIBE, PTTL, PUBLISH, QUIT, RANDOMKEY, RENAME, RENAMENX, REPLICAOF, RESTORE, RPOP, RPOPLPUSH, RPUSH, RPUSHX - SADD, SAVE, SCAN, SCARD, SCRIPT EXITS, SCRIPT FLUSH, SCRIPT KILL, SCRIPT LOAD, SDIFF, SDIFFSTORE, SELECT, SENTINEL FAILOVER, SENTINEL MASTERS, SENTINEL MONITOR, SENTINEL REMOVE, SENTINEL SLAVES, SET, SETBIT, SETEX, SETNX, SETRANGE, SHUTDOWN, SINTER, SINTERSTORE, SISMEMBER, SLAVEOF, SMEMBERS, SMOVE, SORT, SPOP, SRANDMEMBER, SREM, SSCAN, STRLEN, SUBSCRIBE, SUNION, SUNIONSTORE, TIME, TTL, TYPE, UNSUBSCRIBE, UNWATCH, WATCH - XACK, XACKDEL, XADD, XAUTOCLAIM, XCLAIM, XDEL, XDELEX, XGROUP, XINFO, XLEN, XPENDING, XRANGE, XREAD, XREADGROUP ``` -------------------------------- ### Perform Partial Updates with Spring Data Redis Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/usage.adoc Demonstrates how to use the PartialUpdate class to modify specific fields of a Redis entity without replacing the entire object. It includes examples of setting simple properties, removing fields, and managing TTL expiration. ```java PartialUpdate update = new PartialUpdate("e2c7dcee", Person.class) .set("firstname", "mat") .set("address.city", "emond's field") .del("age") .set("address", new Address("Street", "City")) .set("mapProperty", myMap) .refreshTtl(true) .set("expiration", 1000); template.update(update); ``` -------------------------------- ### Configure Lettuce Client for Observability (Java) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/observability.adoc Manually configures Lettuce client resources to integrate with Micrometer for observability. This involves creating a `ClientResources` bean with tracing enabled and then applying it to the `LettuceClientConfiguration`. This is useful when not using Spring Boot's auto-configuration or requiring full customization. ```java import io.lettuce.core.ClientOptions; import io.lettuce.core.resource.ClientResources; import io.micrometer.core.instrument.observation.ObservationRegistry; import io.micrometer.tracing.otelcompat.otelagent.bridge.MicrometerTracing; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; @Configuration class ObservabilityConfiguration { @Bean public ClientResources clientResources(ObservationRegistry observationRegistry) { return ClientResources.builder() .tracing(new MicrometerTracing(observationRegistry, "my-redis-cache")) .build(); } @Bean public LettuceConnectionFactory lettuceConnectionFactory(ClientResources clientResources) { LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .clientResources(clientResources).build(); RedisConfiguration redisConfiguration = null; // Replace with your actual RedisConfiguration return new LettuceConnectionFactory(redisConfiguration, clientConfig); } } ``` -------------------------------- ### Configure Maven Snapshot Repository Source: https://github.com/spring-projects/spring-data-redis/blob/main/README.adoc Dependency and repository configuration for accessing snapshot versions of Spring Data Redis. ```xml org.springframework.data spring-data-redis ${version}-SNAPSHOT spring-snapshot Spring Snapshot Repository https://repo.spring.io/snapshot ``` -------------------------------- ### Execute Commands Across Redis Cluster using Java Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/cluster.adoc Demonstrates how to use RedisClusterConnection to perform operations across a cluster. It shows both global commands that aggregate results from multiple nodes and node-specific commands for targeted data retrieval. ```java RedisClusterConnection connection = connectionFactory.getClusterConnection(); connection.set("thing1", value); connection.set("thing2", value); // Executes across all master nodes connection.keys("*"); // Executes on specific nodes connection.keys(NODE_7379, "*"); connection.keys(NODE_7380, "*"); connection.keys(NODE_7381, "*"); connection.keys(NODE_7382, "*"); ``` -------------------------------- ### Receive Redis messages with ReactiveRedisMessageListenerContainer Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pubsub-receiving.adoc Demonstrates how to initialize a reactive message listener container and receive messages from a specific Redis channel using a Flux stream. ```java ReactiveRedisConnectionFactory factory = … ReactiveRedisMessageListenerContainer container = new ReactiveRedisMessageListenerContainer(factory); Flux> stream = container.receive(ChannelTopic.of("my-channel")); ``` -------------------------------- ### Apply Sorting to Repository Queries in Java Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/queries.adoc Shows how to implement static sorting via method naming conventions and dynamic sorting by passing a Sort object as a parameter to repository methods. ```java interface PersonRepository extends RedisRepository { List findByFirstnameOrderByAgeDesc(String firstname); List findByFirstname(String firstname, Sort sort); } ``` -------------------------------- ### Synchronize Redis subscriptions with receiveLater Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pubsub-receiving.adoc Uses the receiveLater method to obtain a Mono that completes once the server-side subscription is synchronized, allowing for hooks during the subscription process. ```java ReactiveRedisConnectionFactory factory = … ReactiveRedisMessageListenerContainer container = new ReactiveRedisMessageListenerContainer(factory); Mono>> stream = container.receiveLater(ChannelTopic.of("my-channel")); stream.doOnNext(inner -> // notification hook when Redis subscriptions are synchronized with the server) .flatMapMany(Function.identity()) .…; ``` -------------------------------- ### Subscribe to Redis channels using ReactiveRedisTemplate Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pubsub-receiving.adoc Provides a simplified approach to subscribe to Redis channels directly via the template API. Note that this method is limited as it does not support adding subscriptions after the initial call. ```java redisTemplate.listenToChannel("channel1", "channel2").doOnNext(msg -> { // message processing ... }).subscribe(); ``` -------------------------------- ### Publishing messages with Spring Messaging Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pubsub-sending.adoc Demonstrates using RedisMessageSendingTemplate with payload conversion and content type headers. ```java RedisMessageSendingTemplate template = … template.convertAndSend("chatroom", new Greeting("hello", "world")); template.convertAndSend("chatroom", new Greeting("hello", "world"), <1> Map.of(MessageHeaders.CONTENT_TYPE, "application/json")); template.convertAndSend("chatroom", new Greeting("hello", "world"), <2> Map.of(MessageHeaders.CONTENT_TYPE, JdkSerializerMessageConverter.APPLICATION_JAVA_SERIALIZED_OBJECT_VALUE)); ``` -------------------------------- ### Add Link to Redis List (Reactive) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/template.adoc Shows how to add a URL to a Redis list reactively using ReactiveStringRedisTemplate. This method returns a Mono representing the size of the list after the push operation. ```java public class Example { @Autowired private ReactiveStringRedisTemplate redisTemplate; public Mono addLink(String userId, URL url) { return redisTemplate.opsForList().leftPush(userId, url.toExternalForm()); } } ``` -------------------------------- ### Execute Pipelined Commands with RedisTemplate (Java) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pipelining.adoc Demonstrates running multiple Redis commands within a pipeline using `RedisTemplate.executePipelined`. This method is suitable for bulk operations where results need to be collected and deserialized. The `RedisCallback` should return null as its return value is discarded. ```java List results = stringRedisTemplate.executePipelined( new RedisCallback() { public Object doInRedis(RedisConnection connection) throws DataAccessException { StringRedisConnection stringRedisConn = new DefaultStringRedisConnection(connection); for(int i=0; i< batchSize; i++) { stringRedisConn.rPop("myqueue"); } return null; } }); ``` -------------------------------- ### Redis Commands for Simple Property Index (Text) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/indexes.adoc Illustrates the Redis commands generated when indexing 'firstname' for 'Person' entities. It shows `SADD` commands to add members to sets representing the index. ```text SADD people:firstname:rand e2c7dcee-b8cd-4424-883e-736ce564363e SADD people:firstname:aviendha a9d4b3a0-50d3-4538-a2fc-f7fc2581ee56 ``` -------------------------------- ### Enable and Configure Redis Listener Infrastructure Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pubsub-annotated.adoc Shows how to enable Redis listener annotations using @EnableRedisListeners and configure the required RedisMessageListenerContainer bean. Provided in both Java and Kotlin. ```java @Configuration @EnableRedisListeners public class RedisConfiguration { @Bean public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer factory = new RedisMessageListenerContainer(); factory.setConnectionFactory(connectionFactory); return factory; } } ``` ```kotlin @Configuration @EnableRedisListeners class RedisConfiguration { @Bean fun redisMessageListenerContainer(connectionFactory: RedisConnectionFactory) = RedisMessageListenerContainer().apply { setConnectionFactory(connectionFactory); } } ``` -------------------------------- ### Sample Map Converters for Redis Mapping (Java) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/mapping.adoc Demonstrates custom Java converters for mapping a complex type (Address) to and from a Map. This allows for more granular control over how data is stored in the Redis Hash. ```java @WritingConverter public class AddressToMapConverter implements Converter> { @Override public Map convert(Address source) { return singletonMap("ciudad", source.getCity().getBytes()); } } @ReadingConverter public class MapToAddressConverter implements Converter, Address> { @Override public Address convert(Map source) { return new Address(new String(source.get("ciudad"))); } } ``` -------------------------------- ### Configuring Indexes with @EnableRedisRepositories (Java) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/indexes.adoc Shows how to configure secondary indexes programmatically using an `IndexConfiguration` class and the `@EnableRedisRepositories` annotation. This approach allows defining indexes without modifying domain types. ```java @Configuration @EnableRedisRepositories(indexConfiguration = MyIndexConfiguration.class) public class ApplicationConfig { //... RedisConnectionFactory and RedisTemplate Bean definitions omitted public static class MyIndexConfiguration extends IndexConfiguration { @Override protected Iterable initialConfiguration() { return Collections.singleton(new SimpleIndexDefinition("people", "firstname")); } } } ``` -------------------------------- ### Define Derived Repository Finder Methods in Java Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/queries.adoc Demonstrates how to automatically derive finder queries from method names in a Spring Data Redis repository. Requires properties to be indexed for proper functionality. ```java public interface PersonRepository extends CrudRepository { List findByFirstname(String firstname); } ``` -------------------------------- ### Configure Redis Cache with TTI in Java Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-cache.adoc Demonstrates how to enable TTI and set a default TTL duration within a Spring configuration class using RedisCacheManager. ```java @Configuration @EnableCaching class RedisConfiguration { @Bean RedisConnectionFactory redisConnectionFactory() { // ... } @Bean RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) { RedisCacheConfiguration defaults = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(5)) .enableTimeToIdle(); return RedisCacheManager.builder(connectionFactory) .cacheDefaults(defaults) .build(); } } ``` -------------------------------- ### Configure Read from Replica Strategy Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/connection-modes.adoc Shows how to configure a Lettuce-based connection to read from replicas while writing to the master node using LettuceClientConfiguration. ```java @Configuration class WriteToMasterReadFromReplicaConfiguration { @Bean public LettuceConnectionFactory redisConnectionFactory() { LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .readFrom(REPLICA_PREFERRED) .build(); RedisStandaloneConfiguration serverConfig = new RedisStandaloneConfiguration("server", 6379); return new LettuceConnectionFactory(serverConfig, clientConfig); } } ``` -------------------------------- ### Configure StringRedisTemplate for String Operations Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/template.adoc Configures specialized templates for handling String-based keys and values. These templates use StringRedisSerializer to ensure data remains human-readable in Redis. ```java @Configuration class RedisConfiguration { @Bean LettuceConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(); } @Bean StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } } ``` ```java @Configuration class RedisConfiguration { @Bean LettuceConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(); } @Bean ReactiveStringRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) { return new ReactiveStringRedisTemplate<>(factory); } } ``` ```xml ``` -------------------------------- ### Find Entity via Simple Index Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/redis-repositories/anatomy.adoc Explains the retrieval process using secondary indexes, involving SINTER to find keys and HGETALL to fetch the actual entity data. ```java repository.findByFirstname("egwene"); ``` ```text SINTER "people:firstname:egwene" HGETALL "people:d70091b5-0b9a-4c0a-9551-519e61bc9ef3" ``` -------------------------------- ### Configure Lettuce Pipelining Flush Policy (Java) Source: https://github.com/spring-projects/spring-data-redis/blob/main/src/main/antora/modules/ROOT/pages/redis/pipelining.adoc Shows how to configure the pipelining flush policy for the Lettuce driver in Spring Data Redis. This allows for fine-grained control over when pipelined commands are sent to the server, such as buffering and flushing after a specific number of commands. ```java LettuceConnectionFactory factory = // ... factory.setPipeliningFlushPolicy(PipeliningFlushPolicy.buffered(3)); ```