Spring boot session persist is past of spring boot session management. Sprint boot provide ways to persist session in database like session id, session creation time, last active time, max inactive interval (session timeout) and session attributes.

Key points of Spring boot Rest Service Session Example using JDBC

  • Make sure that you have added @EnableJdbcHttpSession annotation at to enable JDBC Session
  • Make sure that Database properties are current in application.properties files like spring.datasource.urlspring.datasource.username, spring.datasource.password, spring.datasource.driver-class-name.
  • If do not want to write database related properties then create bean @DataSource 
  • Make sure that database drive has been added in classpath or POM
  • HttpSessionStrategy bean requires to maintain session using header (Mostly request for Rest Services)
  • spring-session-jdbc dependency must be available in classpath
  • Copy table schema from org.springframework.session.jdbc.schema-[DATABASE].sql and create table manually. In this example we have used schema-mysql.sql
  • When any session create it will store session related information database tables by default table names are spring_sessionspring_session_attributes.
  • If do not like spring_session table name then specified table in property name spring.session.jdbc.table-name
     like  : spring.session.jdbc.table-name=your_table_spring_session
  • For max_inactive_interval (session timeout) need to specified values in annotation attribute maxInactiveIntervalInSeconds so that values affect in table.
  • @EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 1500)
  • Here are some useful other properties:
  • server.session.timeout= # Session timeout in seconds.
    spring.session.jdbc.initializer.enabled= # Create the required session tables on startup if necessary. Enabled automatically if the default table name is set or a custom schema is configured.
    spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/[email protected]@[email protected]@.sql # Path to the SQL file to use to initialize the database schema.
    spring.session.jdbc.table-name=SPRING_SESSION # Name of database table used to store sessions.

    NOTE : spring.session.jdbc.schema : It is not creating schema automatically. We need to create schema manually. 

Spring boot Rest Service Session Example using JDBC

Spring boot Rest Service Session Example using JDBC

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>spring-boot-example</groupId>
    <artifactId>Spring-boot-session-example-using-jdbc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <description>Spring boot rest service session example using jdbc</description>
    <!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
    </parent>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <!-- Provided -->
        <dependency>
            <groupId>org.springframework.boot</groupId>                <!-- for tomcat web container-->
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>     <!-- for spring boot jdbc session  -->
            <artifactId>spring-session-jdbc</artifactId>
            <version>1.3.1.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>         <!--its for spring mvc related -->
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

 

HttpSessionConfig

package com.javadeveloperzone;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
import org.springframework.session.web.http.HeaderHttpSessionStrategy;
import org.springframework.session.web.http.HttpSessionStrategy;



/**
 * Created by Java Developer Zone on 13-11-2017.
 */
@Configuration
@EnableJdbcHttpSession
public class HttpSessionConfig extends AbstractHttpSessionApplicationInitializer {

    @Bean
    public HttpSessionStrategy httpSessionStrategy() {      // maintain session using header (mostly for rest session management)
        return new HeaderHttpSessionStrategy();
    }

}

SpringBooJDBCSessionController

package com.javadeveloperzone.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;

/**
 * Created by JavaDeveloperZone on 19-07-2017.
 */
@RestController
public class SpringBooJDBCSessionController{

    @GetMapping("/viewSessionData")                     // it will handle all request for /welcome
    public java.util.Map<String,Integer> start(HttpServletRequest request) {
        Integer integer =(Integer) request.getSession().getAttribute("hitCounter");  it will read data from database tables
        if(integer==null){
            integer=new Integer(0);
            integer++;
            request.getSession().setAttribute("hitCounter",integer);  // it will write data to tables
        }else{
            integer++;
            request.getSession().setAttribute("hitCounter",integer);  // it will write data to tables
        }
        java.util.Map<String,Integer> hitCounter=new HashMap<>();
        hitCounter.put("Hit Counter",integer);
        return hitCounter;
    }

}

 

SpringBootConfig

package com.javadeveloperzone;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

/**
 * Created by JavaDeveloperZone on 19-07-2017.
 */

@SpringBootApplication
@ComponentScan
// Using a root package also allows the @ComponentScan annotation to be used without needing to specify a basePackage attribute
public class SpringBootConfig {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootConfig.class, args);            // it wil start application
    }
}

application.properties

spring.datasource.url=jdbc:mysql://localhost/demo_database
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

schema-mysql.sql

CREATE TABLE SPRING_SESSION (
  SESSION_ID CHAR(36) NOT NULL,
  CREATION_TIME BIGINT NOT NULL,
  LAST_ACCESS_TIME BIGINT NOT NULL,
  MAX_INACTIVE_INTERVAL INT NOT NULL,
  PRINCIPAL_NAME VARCHAR(100),
  CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (SESSION_ID)
) ENGINE=InnoDB;

CREATE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (LAST_ACCESS_TIME);

CREATE TABLE SPRING_SESSION_ATTRIBUTES (
  SESSION_ID CHAR(36) NOT NULL,
  ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
  ATTRIBUTE_BYTES BLOB NOT NULL,
  CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
  CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_ID) REFERENCES SPRING_SESSION(SESSION_ID) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_ID);

Run Application

mvn spring-boot:run

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Spring-boot-session-example-using-jdbc 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> spring-boot-maven-plugin:1.5.4.RELEASE:run (default-cli) > test-compile @ Spring-boot-session-example-using-jdbc >>>
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ Spring-boot-session-example-using-jdbc ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ Spring-boot-session-example-using-jdbc ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ Spring-boot-session-example-using-jdbc ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory F:\extrawork\spring-boot\spring-boot-rest-service-session-jdbc-example\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ Spring-boot-session-example-using-jdb
c ---
[INFO] No sources to compile
[INFO]
[INFO] <<< spring-boot-maven-plugin:1.5.4.RELEASE:run (default-cli) < test-compile @ Spring-boot-session-example-using-jdbc <<<
[INFO]
[INFO] --- spring-boot-maven-plugin:1.5.4.RELEASE:run (default-cli) @ Spring-boot-session-example-using-jdbc ---

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.4.RELEASE)

2017-11-25 09:49:51.741  INFO 34908 --- [           main] com.javadeveloperzone.SpringBootConfig   : Starting
SpringBootConfig on Mahesh with PID 34908 (F:\extrawork\spring-boot\spring-boot-rest-service-session-jdbc-exam
ple\target\classes started by Lenovo in F:\extrawork\spring-boot\spring-boot-rest-service-session-jdbc-example
)
2017-11-25 09:49:51.746  INFO 34908 --- [           main] com.javadeveloperzone.SpringBootConfig   : No active

Database:

Table : spring_session

Spring Boot Rest Service Session Example - JDBC

Spring Boot Rest Service Session Example – JDBC

Table : spring_session_attributes

Spring Boot Rest Service Session Example - JDBC - spring-session-attributes

Spring Boot Rest Service Session Example – JDBC – spring-session-attributes

Send First Request, It will create session and store session information in database and return x-auth-token in response header.

Spring Boot Rest Service Session Example - First Request

Spring Boot Rest Service Session Example – First Request

Farther request, Pass header  x-auth-token in request so server will consider same session.

Spring Boot Rest Service Session Example - Pass Header Information

Spring Boot Rest Service Session Example – Pass Header Information

References:

Spring boot session management using jdbc document

 

Was this post helpful?
Let us know, if you liked the post. Only in this way, we can improve us.
Yes
No

4 comments. Leave new

how do you store data to session tables? where do you pass the session details to the tables?

Hi shehan,

When we use session using JDBC at that time spring will manage to store and retrieve data in Tables. We do not need to write any code our end.
When we write session.setAttribute(“Key”,”Value”) at that time spring session will automatically write the value to Tables. In my example, i missed adding controller in the post that added now.

Thank you for the question.

I get this error every time when i hit the REST URL.
org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO SPRING_SESSION(SESSION_ID, CREATION_TIME, LAST_ACCESS_TIME, MAX_INACTIVE_INTERVAL, PRINCIPAL_NAME) VALUES (?, ?, ?, ?, ?)]; NULL not allowed for column “PRIMARY_ID”;
Can someone please guide me here ?

Are you using which version of spring boot?

Leave a Reply

Your email address will not be published. Required fields are marked *