diff --git a/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/AbstractJdbcOperationsSessionRepositoryITests.java b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/AbstractJdbcOperationsSessionRepositoryITests.java index 555ceef2..267862cf 100644 --- a/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/AbstractJdbcOperationsSessionRepositoryITests.java +++ b/spring-session-jdbc/src/integration-test/java/org/springframework/session/jdbc/AbstractJdbcOperationsSessionRepositoryITests.java @@ -811,6 +811,21 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests { .isEqualTo("value2"); } + @Test // gh-1203 + public void saveWithLargeAttribute() { + String attributeName = "largeAttribute"; + int arraySize = 4000; + + JdbcOperationsSessionRepository.JdbcSession session = this.repository + .createSession(); + session.setAttribute(attributeName, new byte[arraySize]); + this.repository.save(session); + session = this.repository.findById(session.getId()); + + assertThat(session).isNotNull(); + assertThat((byte[]) session.getAttribute(attributeName)).hasSize(arraySize); + } + private String getSecurityName() { return this.context.getAuthentication().getName(); } 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 45f35ee7..cc5d156d 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 @@ -35,6 +35,9 @@ import org.springframework.core.serializer.support.DeserializingConverter; import org.springframework.core.serializer.support.SerializingConverter; import org.springframework.core.type.AnnotationMetadata; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.support.JdbcUtils; +import org.springframework.jdbc.support.MetaDataAccessException; +import org.springframework.jdbc.support.lob.DefaultLobHandler; import org.springframework.jdbc.support.lob.LobHandler; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; @@ -102,6 +105,11 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration if (this.lobHandler != null) { sessionRepository.setLobHandler(this.lobHandler); } + else if (requiresTemporaryLob(this.dataSource)) { + DefaultLobHandler lobHandler = new DefaultLobHandler(); + lobHandler.setCreateTemporaryLob(true); + sessionRepository.setLobHandler(lobHandler); + } if (this.springSessionConversionService != null) { sessionRepository.setConversionService(this.springSessionConversionService); } @@ -115,6 +123,17 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration return sessionRepository; } + private static boolean requiresTemporaryLob(DataSource dataSource) { + try { + String productName = JdbcUtils.extractDatabaseMetaData(dataSource, + "getDatabaseProductName"); + return "Oracle".equalsIgnoreCase(JdbcUtils.commonDatabaseName(productName)); + } + catch (MetaDataAccessException ex) { + return false; + } + } + public void setMaxInactiveIntervalInSeconds(Integer maxInactiveIntervalInSeconds) { this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; }