From d667acf91ae931cac04641090ac5168d66808daf Mon Sep 17 00:00:00 2001 From: Brian Sam-Bodden Date: Sun, 7 Dec 2025 21:36:29 -0700 Subject: [PATCH] fix: resolve Spring Boot 4.0.0 compatibility issues (#697) Fix two issues reported when using Redis OM Spring 2.0.0 with Spring Boot 4.0.0: 1. Bean definition conflict: Update RedisRepositoriesExcludeFilter to exclude the new modular autoconfiguration class name used in Spring Boot 4.0 (DataRedisRepositoriesAutoConfiguration) in addition to the legacy class name. 2. Missing JedisConnectionFactory: Add JedisConnectionFactory and StringRedisTemplate beans to RedisModulesConfiguration that are created when Spring Boot's Redis autoconfiguration is not present. This ensures Redis OM Spring works regardless of whether spring-boot-data-redis is explicitly included. Also fix spring.factories formatting (missing line continuation backslash). --- .../om/spring/RedisModulesConfiguration.java | 63 +++++++++++++++++++ .../RedisRepositoriesExcludeFilter.java | 5 +- .../main/resources/META-INF/spring.factories | 2 +- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/RedisModulesConfiguration.java b/redis-om-spring/src/main/java/com/redis/om/spring/RedisModulesConfiguration.java index 32e4e04b1..843fe0aea 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/RedisModulesConfiguration.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/RedisModulesConfiguration.java @@ -22,7 +22,10 @@ import org.springframework.context.annotation.*; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.EventListener; +import org.springframework.core.env.Environment; import org.springframework.data.geo.Point; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.jedis.JedisClientConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisHash; import org.springframework.data.redis.core.RedisOperations; @@ -132,6 +135,66 @@ public RedisEnhancedMappingContext redisMappingContext() { return new RedisEnhancedMappingContext(); } + /** + * Creates a Jedis connection factory for Redis connectivity. + *

+ * This bean is required by Redis OM Spring for Redis Stack modules support. + * It will be created if no JedisConnectionFactory bean exists, ensuring + * Jedis is used instead of Lettuce (which is Spring Boot 4.0's default). + *

+ * Connection settings are read from standard Spring Data Redis properties: + *

+ * + * @param environment the Spring environment for reading configuration properties + * @return the configured Jedis connection factory + */ + @Bean( + name = "jedisConnectionFactory" + ) + @Primary + @ConditionalOnMissingBean( + JedisConnectionFactory.class + ) + public JedisConnectionFactory jedisConnectionFactory(Environment environment) { + String host = environment.getProperty("spring.data.redis.host", "localhost"); + int port = environment.getProperty("spring.data.redis.port", Integer.class, 6379); + String password = environment.getProperty("spring.data.redis.password"); + int database = environment.getProperty("spring.data.redis.database", Integer.class, 0); + + RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration(host, port); + redisConfig.setDatabase(database); + if (password != null && !password.isEmpty()) { + redisConfig.setPassword(password); + } + + JedisClientConfiguration clientConfig = JedisClientConfiguration.builder().build(); + + return new JedisConnectionFactory(redisConfig, clientConfig); + } + + /** + * Creates a StringRedisTemplate for string-based Redis operations. + *

+ * This bean is required by Redis OM Spring and will be created if Spring Boot's + * Redis autoconfiguration hasn't already created one. It uses the JedisConnectionFactory + * for connectivity. + * + * @param connectionFactory the Jedis connection factory + * @return the configured StringRedisTemplate + */ + @Bean + @ConditionalOnMissingBean( + StringRedisTemplate.class + ) + public StringRedisTemplate stringRedisTemplate(JedisConnectionFactory connectionFactory) { + return new StringRedisTemplate(connectionFactory); + } + /** * Creates a configured Gson builder for JSON serialization and deserialization. *

diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/RedisRepositoriesExcludeFilter.java b/redis-om-spring/src/main/java/com/redis/om/spring/RedisRepositoriesExcludeFilter.java index 65cdc94b6..a7dc97c75 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/RedisRepositoriesExcludeFilter.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/RedisRepositoriesExcludeFilter.java @@ -33,7 +33,10 @@ public RedisRepositoriesExcludeFilter() { } private static final Set SHOULD_SKIP = new HashSet<>(List.of( - "org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration")); + // Spring Boot 3.x class name + "org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration", + // Spring Boot 4.0+ class name (modular autoconfigure) + "org.springframework.boot.data.redis.autoconfigure.DataRedisRepositoriesAutoConfiguration")); @Override public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) { diff --git a/redis-om-spring/src/main/resources/META-INF/spring.factories b/redis-om-spring/src/main/resources/META-INF/spring.factories index bc1f6e8e3..38e83a478 100644 --- a/redis-om-spring/src/main/resources/META-INF/spring.factories +++ b/redis-om-spring/src/main/resources/META-INF/spring.factories @@ -1,6 +1,6 @@ # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -com.redis.om.spring.RedisModulesConfiguration +com.redis.om.spring.RedisModulesConfiguration,\ com.redis.om.spring.EntraIDConfiguration org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\ com.redis.om.spring.RedisRepositoriesExcludeFilter