diff --git a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryITests.java b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryITests.java index 89188f6e5..899aa4b2b 100644 --- a/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryITests.java +++ b/spring-session-data-redis/src/integration-test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryITests.java @@ -17,6 +17,7 @@ package org.springframework.session.data.redis; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -151,6 +152,21 @@ void saveThenSaveSessionKeyAndShadowKeyWith5MinutesDifference() { assertThat(differenceInSeconds).isEqualTo(300); } + @Test + void saveNonExpiringThenSaveSessionKeyAndShadowKeyWithNoDifference() { + RedisSession toSave = this.repository.createSession(); + String expectedAttributeName = "a"; + String expectedAttributeValue = "b"; + toSave.setAttribute(expectedAttributeName, expectedAttributeValue); + toSave.setMaxInactiveInterval(Duration.ofMillis(-1)); + + this.repository.save(toSave); + + Long sessionKeyExpire = this.redis.getExpire("RedisIndexedSessionRepositoryITests:sessions:" + toSave.getId(), + TimeUnit.SECONDS); + assertThat(sessionKeyExpire).isEqualTo(-1); + } + @Test void putAllOnSingleAttrDoesNotRemoveOld() { RedisSession toSave = this.repository.createSession(); diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisIndexedSessionRepository.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisIndexedSessionRepository.java index 891ff88f9..de2b6c685 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisIndexedSessionRepository.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/RedisIndexedSessionRepository.java @@ -929,9 +929,11 @@ private void saveDelta() { createShadowKey(sessionExpireInSeconds); - long fiveMinutesAfterExpires = sessionExpireInSeconds + TimeUnit.MINUTES.toSeconds(5); - RedisIndexedSessionRepository.this.sessionRedisOperations.boundHashOps(getSessionKey(getId())) - .expire(fiveMinutesAfterExpires, TimeUnit.SECONDS); + if (sessionExpireInSeconds > 0) { + long fiveMinutesAfterExpires = sessionExpireInSeconds + TimeUnit.MINUTES.toSeconds(5); + RedisIndexedSessionRepository.this.sessionRedisOperations.boundHashOps(getSessionKey(getId())) + .expire(fiveMinutesAfterExpires, TimeUnit.SECONDS); + } RedisIndexedSessionRepository.this.expirationStore.save(this); this.delta = new HashMap<>(this.delta.size()); @@ -1036,8 +1038,11 @@ public void save(RedisSession session) { String expirationsKey = getExpirationsKey(toExpire); long sessionExpireInSeconds = session.getMaxInactiveInterval().getSeconds(); - long fiveMinutesAfterExpires = sessionExpireInSeconds + TimeUnit.MINUTES.toSeconds(5); - this.redis.boundSetOps(expirationsKey).expire(fiveMinutesAfterExpires, TimeUnit.SECONDS); + + if (sessionExpireInSeconds > 0) { + long fiveMinutesAfterExpires = sessionExpireInSeconds + TimeUnit.MINUTES.toSeconds(5); + this.redis.boundSetOps(expirationsKey).expire(fiveMinutesAfterExpires, TimeUnit.SECONDS); + } String expireKey = getExpirationKey(toExpire); BoundSetOperations expireOperations = this.redis.boundSetOps(expireKey); diff --git a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryTests.java b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryTests.java index 1ac304e65..d26fe7668 100644 --- a/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryTests.java +++ b/spring-session-data-redis/src/test/java/org/springframework/session/data/redis/RedisIndexedSessionRepositoryTests.java @@ -271,6 +271,21 @@ void saveSetAttribute() { map(RedisIndexedSessionRepository.getSessionAttrNameKey(attrName), session.getAttribute(attrName))); } + @Test + void saveNonExpiring() { + RedisSession session = this.redisRepository.new RedisSession(new MapSession(), false); + session.setMaxInactiveInterval(Duration.ofSeconds(-1)); + + given(this.redisOperations.boundHashOps(anyString())).willReturn(this.boundHashOperations); + given(this.redisOperations.boundSetOps(anyString())).willReturn(this.boundSetOperations); + given(this.redisOperations.boundValueOps(anyString())).willReturn(this.boundValueOperations); + + this.redisRepository.save(session); + + verify(this.boundHashOperations, never()).expire(-1, TimeUnit.SECONDS); + assertThat(getDelta()).isEqualTo(map(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY, -1)); + } + @Test void saveRemoveAttribute() { String attrName = "attrName";