diff --git a/spring-session-docs/src/test/java/docs/IndexDocTests.java b/spring-session-docs/src/test/java/docs/IndexDocTests.java
index 3471535d..3e61f605 100644
--- a/spring-session-docs/src/test/java/docs/IndexDocTests.java
+++ b/spring-session-docs/src/test/java/docs/IndexDocTests.java
@@ -30,7 +30,6 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.mock.web.MockServletContext;
import org.springframework.session.MapSession;
import org.springframework.session.MapSessionRepository;
@@ -42,7 +41,7 @@ import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.hazelcast.HazelcastSessionRepository;
import org.springframework.session.jdbc.JdbcOperationsSessionRepository;
import org.springframework.session.web.http.SessionRepositoryFilter;
-import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@@ -162,14 +161,14 @@ class IndexDocTests {
// tag::new-jdbcoperationssessionrepository[]
JdbcTemplate jdbcTemplate = new JdbcTemplate();
- // ... configure JdbcTemplate ...
+ // ... configure jdbcTemplate ...
- PlatformTransactionManager transactionManager = new DataSourceTransactionManager();
+ TransactionTemplate transactionTemplate = new TransactionTemplate();
- // ... configure transactionManager ...
+ // ... configure transactionTemplate ...
SessionRepository extends Session> repository = new JdbcOperationsSessionRepository(jdbcTemplate,
- transactionManager);
+ transactionTemplate);
// end::new-jdbcoperationssessionrepository[]
}
diff --git a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/JdbcOperationsSessionRepository.java b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/JdbcOperationsSessionRepository.java
index 23fe757d..11a4bbe4 100644
--- a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/JdbcOperationsSessionRepository.java
+++ b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/JdbcOperationsSessionRepository.java
@@ -42,7 +42,6 @@ import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcOperations;
-import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobHandler;
@@ -56,8 +55,6 @@ import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
-import org.springframework.transaction.TransactionStatus;
-import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionOperations;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
@@ -75,16 +72,16 @@ import org.springframework.util.StringUtils;
*
* // ... configure jdbcTemplate ...
*
- * PlatformTransactionManager transactionManager = new DataSourceTransactionManager();
+ * TransactionTemplate transactionTemplate = new TransactionTemplate();
*
- * // ... configure transactionManager ...
+ * // ... configure transactionTemplate ...
*
* JdbcOperationsSessionRepository sessionRepository =
- * new JdbcOperationsSessionRepository(jdbcTemplate, transactionManager);
+ * new JdbcOperationsSessionRepository(jdbcTemplate, transactionTemplate);
*
*
- * For additional information on how to create and configure {@link JdbcTemplate} and
- * {@link PlatformTransactionManager}, refer to the
* Spring Framework Reference Documentation.
*
@@ -200,12 +197,12 @@ public class JdbcOperationsSessionRepository
private final JdbcOperations jdbcOperations;
+ private final TransactionOperations transactionOperations;
+
private final ResultSetExtractor> extractor = new SessionResultSetExtractor();
private final IndexResolver indexResolver;
- private TransactionOperations transactionOperations = TransactionOperations.withoutTransaction();
-
/**
* The name of database table used by Spring Session to store sessions.
*/
@@ -237,12 +234,30 @@ public class JdbcOperationsSessionRepository
private ConversionService conversionService;
- private LobHandler lobHandler = new DefaultLobHandler();
+ private LobHandler lobHandler;
private FlushMode flushMode = FlushMode.ON_SAVE;
private SaveMode saveMode = SaveMode.ON_SET_ATTRIBUTE;
+ /**
+ * Create a new {@link JdbcOperationsSessionRepository} instance which uses the
+ * provided {@link JdbcOperations} and {@link TransactionOperations} to manage
+ * sessions.
+ * @param jdbcOperations the {@link JdbcOperations} to use
+ * @param transactionOperations the {@link TransactionOperations} to use
+ */
+ public JdbcOperationsSessionRepository(JdbcOperations jdbcOperations, TransactionOperations transactionOperations) {
+ Assert.notNull(jdbcOperations, "jdbcOperations must not be null");
+ Assert.notNull(transactionOperations, "transactionOperations must not be null");
+ this.jdbcOperations = jdbcOperations;
+ this.transactionOperations = transactionOperations;
+ this.indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>());
+ this.conversionService = createDefaultConversionService();
+ this.lobHandler = new DefaultLobHandler();
+ prepareQueries();
+ }
+
/**
* Create a new {@link JdbcOperationsSessionRepository} instance which uses the
* provided {@link JdbcOperations} to manage sessions.
@@ -251,12 +266,13 @@ public class JdbcOperationsSessionRepository
* propagation level of {@link TransactionDefinition#PROPAGATION_REQUIRES_NEW}.
* @param jdbcOperations the {@link JdbcOperations} to use
* @param transactionManager the {@link PlatformTransactionManager} to use
+ * @deprecated since 2.2.0 in favor of
+ * {@link #JdbcOperationsSessionRepository(JdbcOperations, TransactionOperations)}
*/
+ @Deprecated
public JdbcOperationsSessionRepository(JdbcOperations jdbcOperations,
PlatformTransactionManager transactionManager) {
- this(jdbcOperations);
- Assert.notNull(transactionManager, "TransactionManager must not be null");
- this.transactionOperations = createTransactionTemplate(transactionManager);
+ this(jdbcOperations, createTransactionTemplate(transactionManager));
}
/**
@@ -265,13 +281,12 @@ public class JdbcOperationsSessionRepository
*
* The created instance will not execute data access operations in a transaction.
* @param jdbcOperations the {@link JdbcOperations} to use
+ * @deprecated since 2.2.0 in favor of
+ * {@link #JdbcOperationsSessionRepository(JdbcOperations, TransactionOperations)}
*/
+ @Deprecated
public JdbcOperationsSessionRepository(JdbcOperations jdbcOperations) {
- Assert.notNull(jdbcOperations, "JdbcOperations must not be null");
- this.jdbcOperations = jdbcOperations;
- this.indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>());
- this.conversionService = createDefaultConversionService();
- prepareQueries();
+ this(jdbcOperations, TransactionOperations.withoutTransaction());
}
/**
@@ -448,15 +463,8 @@ public class JdbcOperationsSessionRepository
@Override
public void deleteById(final String id) {
- this.transactionOperations.execute(new TransactionCallbackWithoutResult() {
-
- @Override
- protected void doInTransactionWithoutResult(TransactionStatus status) {
- JdbcOperationsSessionRepository.this.jdbcOperations
- .update(JdbcOperationsSessionRepository.this.deleteSessionQuery, id);
- }
-
- });
+ this.transactionOperations.execute(() -> JdbcOperationsSessionRepository.this.jdbcOperations
+ .update(JdbcOperationsSessionRepository.this.deleteSessionQuery, id));
}
@Override
@@ -581,6 +589,7 @@ public class JdbcOperationsSessionRepository
}
private static TransactionTemplate createTransactionTemplate(PlatformTransactionManager transactionManager) {
+ Assert.notNull(transactionManager, "transactionManager must not be null");
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
transactionTemplate.afterPropertiesSet();
@@ -805,71 +814,59 @@ public class JdbcOperationsSessionRepository
private void save() {
if (this.isNew) {
- JdbcOperationsSessionRepository.this.transactionOperations
- .execute(new TransactionCallbackWithoutResult() {
-
- @Override
- protected void doInTransactionWithoutResult(TransactionStatus status) {
- Map indexes = JdbcOperationsSessionRepository.this.indexResolver
- .resolveIndexesFor(JdbcSession.this);
- JdbcOperationsSessionRepository.this.jdbcOperations
- .update(JdbcOperationsSessionRepository.this.createSessionQuery, (ps) -> {
- ps.setString(1, JdbcSession.this.primaryKey);
- ps.setString(2, getId());
- ps.setLong(3, getCreationTime().toEpochMilli());
- ps.setLong(4, getLastAccessedTime().toEpochMilli());
- ps.setInt(5, (int) getMaxInactiveInterval().getSeconds());
- ps.setLong(6, getExpiryTime().toEpochMilli());
- ps.setString(7, indexes.get(PRINCIPAL_NAME_INDEX_NAME));
- });
- Set attributeNames = getAttributeNames();
- if (!attributeNames.isEmpty()) {
- insertSessionAttributes(JdbcSession.this, new ArrayList<>(attributeNames));
- }
- }
-
- });
+ JdbcOperationsSessionRepository.this.transactionOperations.execute(() -> {
+ Map indexes = JdbcOperationsSessionRepository.this.indexResolver
+ .resolveIndexesFor(JdbcSession.this);
+ JdbcOperationsSessionRepository.this.jdbcOperations
+ .update(JdbcOperationsSessionRepository.this.createSessionQuery, (ps) -> {
+ ps.setString(1, JdbcSession.this.primaryKey);
+ ps.setString(2, getId());
+ ps.setLong(3, getCreationTime().toEpochMilli());
+ ps.setLong(4, getLastAccessedTime().toEpochMilli());
+ ps.setInt(5, (int) getMaxInactiveInterval().getSeconds());
+ ps.setLong(6, getExpiryTime().toEpochMilli());
+ ps.setString(7, indexes.get(PRINCIPAL_NAME_INDEX_NAME));
+ });
+ Set attributeNames = getAttributeNames();
+ if (!attributeNames.isEmpty()) {
+ insertSessionAttributes(JdbcSession.this, new ArrayList<>(attributeNames));
+ }
+ });
}
else {
- JdbcOperationsSessionRepository.this.transactionOperations
- .execute(new TransactionCallbackWithoutResult() {
-
- @Override
- protected void doInTransactionWithoutResult(TransactionStatus status) {
- if (JdbcSession.this.changed) {
- Map indexes = JdbcOperationsSessionRepository.this.indexResolver
- .resolveIndexesFor(JdbcSession.this);
- JdbcOperationsSessionRepository.this.jdbcOperations
- .update(JdbcOperationsSessionRepository.this.updateSessionQuery, (ps) -> {
- ps.setString(1, getId());
- ps.setLong(2, getLastAccessedTime().toEpochMilli());
- ps.setInt(3, (int) getMaxInactiveInterval().getSeconds());
- ps.setLong(4, getExpiryTime().toEpochMilli());
- ps.setString(5, indexes.get(PRINCIPAL_NAME_INDEX_NAME));
- ps.setString(6, JdbcSession.this.primaryKey);
- });
- }
- List addedAttributeNames = JdbcSession.this.delta.entrySet().stream()
- .filter((entry) -> entry.getValue() == DeltaValue.ADDED).map(Map.Entry::getKey)
- .collect(Collectors.toList());
- if (!addedAttributeNames.isEmpty()) {
- insertSessionAttributes(JdbcSession.this, addedAttributeNames);
- }
- List updatedAttributeNames = JdbcSession.this.delta.entrySet().stream()
- .filter((entry) -> entry.getValue() == DeltaValue.UPDATED)
- .map(Map.Entry::getKey).collect(Collectors.toList());
- if (!updatedAttributeNames.isEmpty()) {
- updateSessionAttributes(JdbcSession.this, updatedAttributeNames);
- }
- List removedAttributeNames = JdbcSession.this.delta.entrySet().stream()
- .filter((entry) -> entry.getValue() == DeltaValue.REMOVED)
- .map(Map.Entry::getKey).collect(Collectors.toList());
- if (!removedAttributeNames.isEmpty()) {
- deleteSessionAttributes(JdbcSession.this, removedAttributeNames);
- }
- }
-
- });
+ JdbcOperationsSessionRepository.this.transactionOperations.execute(() -> {
+ if (JdbcSession.this.changed) {
+ Map indexes = JdbcOperationsSessionRepository.this.indexResolver
+ .resolveIndexesFor(JdbcSession.this);
+ JdbcOperationsSessionRepository.this.jdbcOperations
+ .update(JdbcOperationsSessionRepository.this.updateSessionQuery, (ps) -> {
+ ps.setString(1, getId());
+ ps.setLong(2, getLastAccessedTime().toEpochMilli());
+ ps.setInt(3, (int) getMaxInactiveInterval().getSeconds());
+ ps.setLong(4, getExpiryTime().toEpochMilli());
+ ps.setString(5, indexes.get(PRINCIPAL_NAME_INDEX_NAME));
+ ps.setString(6, JdbcSession.this.primaryKey);
+ });
+ }
+ List addedAttributeNames = JdbcSession.this.delta.entrySet().stream()
+ .filter((entry) -> entry.getValue() == DeltaValue.ADDED).map(Map.Entry::getKey)
+ .collect(Collectors.toList());
+ if (!addedAttributeNames.isEmpty()) {
+ insertSessionAttributes(JdbcSession.this, addedAttributeNames);
+ }
+ List updatedAttributeNames = JdbcSession.this.delta.entrySet().stream()
+ .filter((entry) -> entry.getValue() == DeltaValue.UPDATED).map(Map.Entry::getKey)
+ .collect(Collectors.toList());
+ if (!updatedAttributeNames.isEmpty()) {
+ updateSessionAttributes(JdbcSession.this, updatedAttributeNames);
+ }
+ List removedAttributeNames = JdbcSession.this.delta.entrySet().stream()
+ .filter((entry) -> entry.getValue() == DeltaValue.REMOVED).map(Map.Entry::getKey)
+ .collect(Collectors.toList());
+ if (!removedAttributeNames.isEmpty()) {
+ deleteSessionAttributes(JdbcSession.this, removedAttributeNames);
+ }
+ });
}
clearChangeFlags();
}
diff --git a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java
index 2355e052..33c7d30b 100644
--- a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java
+++ b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java
@@ -50,6 +50,9 @@ import org.springframework.session.jdbc.JdbcOperationsSessionRepository;
import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.support.TransactionOperations;
+import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
@@ -87,6 +90,8 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
private PlatformTransactionManager transactionManager;
+ private TransactionOperations transactionOperations;
+
private LobHandler lobHandler;
private ConversionService springSessionConversionService;
@@ -100,8 +105,11 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
@Bean
public JdbcOperationsSessionRepository sessionRepository() {
JdbcTemplate jdbcTemplate = createJdbcTemplate(this.dataSource);
+ if (this.transactionOperations == null) {
+ this.transactionOperations = createTransactionTemplate(this.transactionManager);
+ }
JdbcOperationsSessionRepository sessionRepository = new JdbcOperationsSessionRepository(jdbcTemplate,
- this.transactionManager);
+ this.transactionOperations);
if (StringUtils.hasText(this.tableName)) {
sessionRepository.setTableName(this.tableName);
}
@@ -123,7 +131,7 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
sessionRepository.setConversionService(this.conversionService);
}
else {
- sessionRepository.setConversionService(createConversionServiceWithBeanClassLoader());
+ sessionRepository.setConversionService(createConversionServiceWithBeanClassLoader(this.classLoader));
}
return sessionRepository;
}
@@ -173,6 +181,12 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
this.transactionManager = transactionManager;
}
+ @Autowired(required = false)
+ @Qualifier("springSessionTransactionOperations")
+ public void setTransactionOperations(TransactionOperations transactionOperations) {
+ this.transactionOperations = transactionOperations;
+ }
+
@Autowired(required = false)
@Qualifier("springSessionLobHandler")
public void setLobHandler(LobHandler lobHandler) {
@@ -230,10 +244,17 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
return jdbcTemplate;
}
- private GenericConversionService createConversionServiceWithBeanClassLoader() {
+ private static TransactionTemplate createTransactionTemplate(PlatformTransactionManager transactionManager) {
+ TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
+ transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
+ transactionTemplate.afterPropertiesSet();
+ return transactionTemplate;
+ }
+
+ private static GenericConversionService createConversionServiceWithBeanClassLoader(ClassLoader classLoader) {
GenericConversionService conversionService = new GenericConversionService();
conversionService.addConverter(Object.class, byte[].class, new SerializingConverter());
- conversionService.addConverter(byte[].class, Object.class, new DeserializingConverter(this.classLoader));
+ conversionService.addConverter(byte[].class, Object.class, new DeserializingConverter(classLoader));
return conversionService;
}
diff --git a/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/JdbcOperationsSessionRepositoryTests.java b/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/JdbcOperationsSessionRepositoryTests.java
index 603b4ee7..adf4665c 100644
--- a/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/JdbcOperationsSessionRepositoryTests.java
+++ b/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/JdbcOperationsSessionRepositoryTests.java
@@ -28,6 +28,8 @@ import java.util.function.Supplier;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcOperations;
@@ -43,24 +45,18 @@ import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.session.jdbc.JdbcOperationsSessionRepository.JdbcSession;
import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.support.TransactionOperations;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.endsWith;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.startsWith;
import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Tests for {@link JdbcOperationsSessionRepository}.
@@ -73,29 +69,39 @@ class JdbcOperationsSessionRepositoryTests {
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
- private JdbcOperations jdbcOperations = mock(JdbcOperations.class);
-
- private PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class);
+ @Mock
+ private JdbcOperations jdbcOperations;
private JdbcOperationsSessionRepository repository;
@BeforeEach
void setUp() {
- this.repository = new JdbcOperationsSessionRepository(this.jdbcOperations, this.transactionManager);
+ MockitoAnnotations.initMocks(this);
+ this.repository = new JdbcOperationsSessionRepository(this.jdbcOperations,
+ TransactionOperations.withoutTransaction());
}
@Test
void constructorNullJdbcOperations() {
assertThatIllegalArgumentException()
- .isThrownBy(() -> new JdbcOperationsSessionRepository(null, this.transactionManager))
- .withMessage("JdbcOperations must not be null");
+ .isThrownBy(() -> new JdbcOperationsSessionRepository(null, TransactionOperations.withoutTransaction()))
+ .withMessage("jdbcOperations must not be null");
}
@Test
- void constructorNullTransactionManager() {
+ void constructorNullTransactionOperations() {
assertThatIllegalArgumentException()
- .isThrownBy(() -> new JdbcOperationsSessionRepository(this.jdbcOperations, null))
- .withMessage("TransactionManager must not be null");
+ .isThrownBy(
+ () -> new JdbcOperationsSessionRepository(this.jdbcOperations, (TransactionOperations) null))
+ .withMessage("transactionOperations must not be null");
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ void constructorNullTransactionManager() {
+ assertThatIllegalArgumentException().isThrownBy(
+ () -> new JdbcOperationsSessionRepository(this.jdbcOperations, (PlatformTransactionManager) null))
+ .withMessage("transactionManager must not be null");
}
@Test
@@ -248,7 +254,7 @@ class JdbcOperationsSessionRepositoryTests {
assertThat(session.isNew()).isTrue();
assertThat(session.getMaxInactiveInterval()).isEqualTo(new MapSession().getMaxInactiveInterval());
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -260,7 +266,7 @@ class JdbcOperationsSessionRepositoryTests {
assertThat(session.isNew()).isTrue();
assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration.ofSeconds(interval));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -268,7 +274,6 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.setFlushMode(FlushMode.IMMEDIATE);
JdbcSession session = this.repository.createSession();
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations).update(startsWith("INSERT"), isA(PreparedStatementSetter.class));
verifyNoMoreInteractions(this.jdbcOperations);
}
@@ -280,9 +285,8 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT"), isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -293,12 +297,11 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION("),
isA(PreparedStatementSetter.class));
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -310,12 +313,11 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION("),
isA(PreparedStatementSetter.class));
verify(this.jdbcOperations, times(1)).batchUpdate(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
isA(BatchPreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -327,10 +329,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -343,10 +344,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).batchUpdate(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
isA(BatchPreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -360,10 +360,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).update(startsWith("UPDATE SPRING_SESSION_ATTRIBUTES SET"),
isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -379,10 +378,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).batchUpdate(startsWith("UPDATE SPRING_SESSION_ATTRIBUTES SET"),
isA(BatchPreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -396,10 +394,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).update(startsWith("DELETE FROM SPRING_SESSION_ATTRIBUTES WHERE"),
isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -411,8 +408,7 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -428,10 +424,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).batchUpdate(startsWith("DELETE FROM SPRING_SESSION_ATTRIBUTES WHERE"),
isA(BatchPreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test // gh-1070
@@ -444,10 +439,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test // gh-1070
@@ -460,8 +454,7 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test // gh-1070
@@ -476,10 +469,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations).update(startsWith("DELETE FROM SPRING_SESSION_ATTRIBUTES WHERE"),
isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test // gh-1070
@@ -494,10 +486,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations).update(startsWith("UPDATE SPRING_SESSION_ATTRIBUTES SET"),
isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -509,10 +500,9 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).update(startsWith("UPDATE SPRING_SESSION SET"),
isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -523,7 +513,7 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
assertThat(session.isNew()).isFalse();
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -536,7 +526,6 @@ class JdbcOperationsSessionRepositoryTests {
JdbcOperationsSessionRepository.JdbcSession session = this.repository.findById(sessionId);
assertThat(session).isNull();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).query(isA(String.class), isA(PreparedStatementSetter.class),
isA(ResultSetExtractor.class));
}
@@ -552,7 +541,6 @@ class JdbcOperationsSessionRepositoryTests {
JdbcOperationsSessionRepository.JdbcSession session = this.repository.findById(expired.getId());
assertThat(session).isNull();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).query(isA(String.class), isA(PreparedStatementSetter.class),
isA(ResultSetExtractor.class));
verify(this.jdbcOperations, times(1)).update(startsWith("DELETE"), eq(expired.getId()));
@@ -571,7 +559,6 @@ class JdbcOperationsSessionRepositoryTests {
assertThat(session.getId()).isEqualTo(saved.getId());
assertThat(session.isNew()).isFalse();
assertThat(session.getAttribute("savedName")).isEqualTo("savedValue");
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).query(isA(String.class), isA(PreparedStatementSetter.class),
isA(ResultSetExtractor.class));
}
@@ -582,7 +569,6 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.deleteById(sessionId);
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).update(startsWith("DELETE"), eq(sessionId));
}
@@ -594,7 +580,7 @@ class JdbcOperationsSessionRepositoryTests {
.findByIndexNameAndIndexValue("testIndexName", indexValue);
assertThat(sessions).isEmpty();
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -608,7 +594,6 @@ class JdbcOperationsSessionRepositoryTests {
.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principal);
assertThat(sessions).isEmpty();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).query(isA(String.class), isA(PreparedStatementSetter.class),
isA(ResultSetExtractor.class));
}
@@ -633,7 +618,6 @@ class JdbcOperationsSessionRepositoryTests {
.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principal);
assertThat(sessions).hasSize(2);
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).query(isA(String.class), isA(PreparedStatementSetter.class),
isA(ResultSetExtractor.class));
}
@@ -642,7 +626,6 @@ class JdbcOperationsSessionRepositoryTests {
void cleanupExpiredSessions() {
this.repository.cleanUpExpiredSessions();
- assertPropagationRequiresNew();
verify(this.jdbcOperations, times(1)).update(startsWith("DELETE"), anyLong());
}
@@ -659,84 +642,6 @@ class JdbcOperationsSessionRepositoryTests {
assertThat(session.getAttributeNames()).isEmpty();
}
- @Test
- void saveNewWithoutTransaction() {
- this.repository = new JdbcOperationsSessionRepository(this.jdbcOperations);
- JdbcOperationsSessionRepository.JdbcSession session = this.repository.createSession();
-
- this.repository.save(session);
-
- verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION"),
- isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
- verifyZeroInteractions(this.transactionManager);
- }
-
- @Test
- void saveUpdatedWithoutTransaction() {
- this.repository = new JdbcOperationsSessionRepository(this.jdbcOperations);
- JdbcOperationsSessionRepository.JdbcSession session = this.repository.new JdbcSession(new MapSession(),
- "primaryKey", false);
- session.setLastAccessedTime(Instant.now());
-
- this.repository.save(session);
-
- verify(this.jdbcOperations, times(1)).update(startsWith("UPDATE SPRING_SESSION"),
- isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
- verifyZeroInteractions(this.transactionManager);
- }
-
- @Test
- @SuppressWarnings("unchecked")
- void findByIdWithoutTransaction() {
- given(this.jdbcOperations.query(anyString(), any(PreparedStatementSetter.class), any(ResultSetExtractor.class)))
- .willReturn(Collections.emptyList());
- this.repository = new JdbcOperationsSessionRepository(this.jdbcOperations);
- this.repository.findById("testSessionId");
-
- verify(this.jdbcOperations, times(1)).query(endsWith("WHERE S.SESSION_ID = ?"),
- isA(PreparedStatementSetter.class), isA(ResultSetExtractor.class));
- verifyZeroInteractions(this.jdbcOperations);
- verifyZeroInteractions(this.transactionManager);
- }
-
- @Test
- void deleteByIdWithoutTransaction() {
- this.repository = new JdbcOperationsSessionRepository(this.jdbcOperations);
- this.repository.deleteById("testSessionId");
-
- verify(this.jdbcOperations, times(1)).update(eq("DELETE FROM SPRING_SESSION WHERE SESSION_ID = ?"),
- anyString());
- verifyZeroInteractions(this.jdbcOperations);
- verifyZeroInteractions(this.transactionManager);
- }
-
- @Test
- @SuppressWarnings("unchecked")
- void findByIndexNameAndIndexValueWithoutTransaction() {
- given(this.jdbcOperations.query(anyString(), any(PreparedStatementSetter.class), any(ResultSetExtractor.class)))
- .willReturn(Collections.emptyList());
- this.repository = new JdbcOperationsSessionRepository(this.jdbcOperations);
- this.repository.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
- "testIndexValue");
-
- verify(this.jdbcOperations, times(1)).query(endsWith("WHERE S.PRINCIPAL_NAME = ?"),
- isA(PreparedStatementSetter.class), isA(ResultSetExtractor.class));
- verifyZeroInteractions(this.jdbcOperations);
- verifyZeroInteractions(this.transactionManager);
- }
-
- @Test
- void cleanUpExpiredSessionsWithoutTransaction() {
- this.repository = new JdbcOperationsSessionRepository(this.jdbcOperations);
- this.repository.cleanUpExpiredSessions();
-
- verify(this.jdbcOperations, times(1)).update(eq("DELETE FROM SPRING_SESSION WHERE EXPIRY_TIME < ?"), anyLong());
- verifyZeroInteractions(this.jdbcOperations);
- verifyZeroInteractions(this.transactionManager);
- }
-
@Test
void saveWithSaveModeOnSetAttribute() {
this.repository.setSaveMode(SaveMode.ON_SET_ATTRIBUTE);
@@ -751,7 +656,7 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.save(session);
verify(this.jdbcOperations).update(startsWith("UPDATE SPRING_SESSION_ATTRIBUTES SET"),
isA(PreparedStatementSetter.class));
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -770,7 +675,7 @@ class JdbcOperationsSessionRepositoryTests {
.forClass(BatchPreparedStatementSetter.class);
verify(this.jdbcOperations).batchUpdate(startsWith("UPDATE SPRING_SESSION_ATTRIBUTES SET"), captor.capture());
assertThat(captor.getValue().getBatchSize()).isEqualTo(2);
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -789,7 +694,7 @@ class JdbcOperationsSessionRepositoryTests {
.forClass(BatchPreparedStatementSetter.class);
verify(this.jdbcOperations).batchUpdate(startsWith("UPDATE SPRING_SESSION_ATTRIBUTES SET"), captor.capture());
assertThat(captor.getValue().getBatchSize()).isEqualTo(3);
- verifyZeroInteractions(this.jdbcOperations);
+ verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
@@ -798,7 +703,6 @@ class JdbcOperationsSessionRepositoryTests {
JdbcSession session = this.repository.new JdbcSession(new MapSession(), "primaryKey", false);
String attrName = "someAttribute";
session.setAttribute(attrName, "someValue");
- assertPropagationRequiresNew();
verify(this.jdbcOperations).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES("),
isA(PreparedStatementSetter.class));
verifyNoMoreInteractions(this.jdbcOperations);
@@ -811,7 +715,6 @@ class JdbcOperationsSessionRepositoryTests {
cached.setAttribute("attribute1", "value1");
JdbcSession session = this.repository.new JdbcSession(cached, "primaryKey", false);
session.removeAttribute("attribute1");
- assertPropagationRequiresNew();
verify(this.jdbcOperations).update(startsWith("DELETE FROM SPRING_SESSION_ATTRIBUTES WHERE"),
isA(PreparedStatementSetter.class));
verifyNoMoreInteractions(this.jdbcOperations);
@@ -822,7 +725,6 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.setFlushMode(FlushMode.IMMEDIATE);
JdbcSession session = this.repository.new JdbcSession(new MapSession(), "primaryKey", false);
session.setMaxInactiveInterval(Duration.ofSeconds(1));
- assertPropagationRequiresNew();
verify(this.jdbcOperations).update(startsWith("UPDATE SPRING_SESSION SET"), isA(PreparedStatementSetter.class));
verifyNoMoreInteractions(this.jdbcOperations);
}
@@ -832,16 +734,8 @@ class JdbcOperationsSessionRepositoryTests {
this.repository.setFlushMode(FlushMode.IMMEDIATE);
JdbcSession session = this.repository.new JdbcSession(new MapSession(), "primaryKey", false);
session.setLastAccessedTime(Instant.now());
- assertPropagationRequiresNew();
verify(this.jdbcOperations).update(startsWith("UPDATE SPRING_SESSION SET"), isA(PreparedStatementSetter.class));
verifyNoMoreInteractions(this.jdbcOperations);
}
- private void assertPropagationRequiresNew() {
- ArgumentCaptor argument = ArgumentCaptor.forClass(TransactionDefinition.class);
- verify(this.transactionManager, atLeastOnce()).getTransaction(argument.capture());
- assertThat(argument.getValue().getPropagationBehavior())
- .isEqualTo(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
- }
-
}
diff --git a/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationTests.java b/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationTests.java
index 14aa72d1..96318d16 100644
--- a/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationTests.java
+++ b/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationTests.java
@@ -37,6 +37,8 @@ import org.springframework.session.jdbc.JdbcOperationsSessionRepository;
import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.support.TransactionOperations;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -77,7 +79,10 @@ class JdbcHttpSessionConfigurationTests {
void defaultConfiguration() {
registerAndRefresh(DataSourceConfiguration.class, DefaultConfiguration.class);
- assertThat(this.context.getBean(JdbcOperationsSessionRepository.class)).isNotNull();
+ JdbcOperationsSessionRepository sessionRepository = this.context.getBean(JdbcOperationsSessionRepository.class);
+ assertThat(sessionRepository).isNotNull();
+ assertThat(sessionRepository).extracting("transactionOperations")
+ .hasFieldOrPropertyWithValue("propagationBehavior", TransactionDefinition.PROPAGATION_REQUIRES_NEW);
}
@Test
@@ -225,6 +230,17 @@ class JdbcHttpSessionConfigurationTests {
.withMessageContaining("expected single matching bean but found 2");
}
+ @Test
+ void customTransactionOperationsConfiguration() {
+ registerAndRefresh(DataSourceConfiguration.class, CustomTransactionOperationsConfiguration.class);
+
+ JdbcOperationsSessionRepository repository = this.context.getBean(JdbcOperationsSessionRepository.class);
+ TransactionOperations transactionOperations = this.context.getBean(TransactionOperations.class);
+ assertThat(repository).isNotNull();
+ assertThat(transactionOperations).isNotNull();
+ assertThat(repository).hasFieldOrPropertyWithValue("transactionOperations", transactionOperations);
+ }
+
@Test
void customLobHandlerConfiguration() {
registerAndRefresh(DataSourceConfiguration.class, CustomLobHandlerConfiguration.class);
@@ -417,6 +433,16 @@ class JdbcHttpSessionConfigurationTests {
}
+ @EnableJdbcHttpSession
+ static class CustomTransactionOperationsConfiguration {
+
+ @Bean
+ public TransactionOperations springSessionTransactionOperations() {
+ return TransactionOperations.withoutTransaction();
+ }
+
+ }
+
@EnableJdbcHttpSession
static class CustomLobHandlerConfiguration {