In this article, we will see how to use Spring Session with JDBC.
Introduction
Spring Session provides a transparent approach to resolve limitation of HTTP session. It provides central session management without being tied to container specific solution (e.g. Tomcat, Jetty etc.). It provides different options to store and manage session information. In this article, we will walk through the steps to integrate JDBC with Spring Session.
2. Maven dependencies
We will use Spring Boot in this article but will also outline steps to configure Spring session with JDBC for non Spring Boot applications. We will use MySQL for the setup, but you can use any other database of your choice.
2.1 Spring Boot Maven Configurations
If you are using Spring Boot, you need to add following dependencies in your application’s pom.xml file:
<dependencies>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
<!-- Adding this to have datasource and other feature available to us -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
We need not add the dependency for Spring session as this will be taken care by Spring Boot. Based on above configurations, Spring Boot auto-configuration will handle rest of the configurations for us. As the last step, we need to inform Spring Boot to use jdbc to store session information. Add following property in the application.properties
file:
spring.session.store-type=jdbc # Session store type.
[pullquote align=”normal”]If you are using only a single session module, you can omit above property from your application.properties
file. Spring Boot uses that store implementation automatically. If you have over one implementation, you must specify above property. [/pullquote]
2.2 No Spring Boot Configuration
For non Spring Boot project, we need to add the database dependencies and spring-session-jdbc
to the pom.xml
file:
3. Spring JDBC Session Configuration
Before we use our JDBC backed spring session, we need to add few properties in our application.properties file:
spring.datasource.url=jdbc:mysql://localhost:3306/spring-session-jdbc
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
In order for Spring session to work with our JDBC configurations, it needs to create a certain table in the DB, we can enable this feature with help of following property
spring.session.jdbc.initialize-schema=always
Once we enable these properties If we specify spring.session.jdbc.initialize-schema=never
, then we need to create session tables in manually. Spring session JDBC jar contains SQL scripts to create required schema. You can check this under org.springframework.session.jdbc
package.
Here is the schema for MySQL database:
CREATE TABLE SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
3.1. Spring JDBC Session and @EnableJdbcHttpSession
If you are using @EnableJdbcHttpSession
, above configuration will not work. The reason spring.session.*
do not work for you is because your are using @EnableJdbcHttpSession
. That means we are configuring Spring Session explicitly, so Spring Boot backs off with its auto-configuration. To handle this use case, we have following two options.
- Don’t use
@EnableJdbcHttpSession
and let Spring Boot handle it through auto configuration. - Manually create schema if you continue to use
@EnableJdbcHttpSession
annotation.
4. REST Controller
Let’s create a simple REST controller to see session handling in action:
@RestController
public class GreetingController {
@GetMapping("/")
public @ResponseBody ResponseEntity<List> getMessage(Model model, HttpSession session) {
List greetings = (List) session.getAttribute("GREETING_MESSAGES");
if(greetings == null) {
greetings = new ArrayList<>();
}
return new ResponseEntity<List>(greetings,HttpStatus.OK);
}
@PostMapping("/messages")
public @ResponseBody ResponseEntity<List> saveMessage(@RequestParam("message") String greeting, HttpServletRequest request)
{
List greetings = (List) request.getSession().getAttribute("GREETING_MESSAGES");
if(greetings == null) {
greetings = new ArrayList<>();
request.getSession().setAttribute("GREETING_MESSAGES", greetings);
}
greetings.add(greeting);
return new ResponseEntity<List>(greetings,HttpStatus.OK);
}
}
5. Spring Boot Main Class
here is our Spring Boot main class:
@SpringBootApplication
@EnableJdbcHttpSession
public class SpringSessionWithJdbcApplication {
public static void main(String[] args) {
SpringApplication.run(SpringSessionWithJdbcApplication.class, args);
}
}
The only interesting point is the @EnableJdbcHttpSession
annotation.
6. Session Information in Database
If we run our application and hit the end points. Spring Session with JDBC configuration will handle the session management transparently. Here are the screenshots from the database tables for your reference:
7. Spring Session Magic
Spring session handle this transparently.The @EnableJdbcHttpSession
annotation creates a Spring bean with the name of springSessionRepositoryFilter
that implements Filter. The filter is what is in charge of replacing the HttpSession implementation to be backed by Spring Session.
Summary
In this post, we saw how to use Spring Session with JDBC. We discussed the distinct steps to configure and use JDBC backed session management for our application.Please refer to our GitHub repository for updated code base.