4

I have my application running with spring web mvc framework without spring boot. Now I want to use spring session JDBC to store the session to the database used by the app. All the examples I found online are using spring boot, and if not using spring boot, the datasource config they use are EmbeddedDatabase like this:

    @Bean
    public EmbeddedDatabase dataSource() {
            return new EmbeddedDatabaseBuilder() 
                            .setType(EmbeddedDatabaseType.H2)
                            .addScript("org/springframework/session/jdbc/schema-h2.sql").build();
    }

I have my datasource configuration using HikariCP and I want the spring session to use this datasource config.

@Bean
public DataSource dataSource() {
    HikariConfig config = new HikariConfig();
    config.setDriverClassName(env.getRequiredProperty("jdbc.driver"));
    config.setJdbcUrl(env.getRequiredProperty("jdbc.url"));
    config.setUsername(env.getRequiredProperty("jdbc.username"));
    config.setPassword(env.getRequiredProperty("jdbc.password"));
    config.setMinimumIdle(env.getRequiredProperty("jdbc.pool.minimumIdle", Integer.class));
    config.setMaximumPoolSize(env.getRequiredProperty("jdbc.pool.maximumPoolSize", Integer.class));
    config.addDataSourceProperty("cachePrepStmts", env.getRequiredProperty("jdbc.prop.cachePrepStmts"));
    config.addDataSourceProperty("prepStmtCacheSize", env.getRequiredProperty("jdbc.prop.prepStmtCacheSize"));
    config.addDataSourceProperty("prepStmtCacheSqlLimit", env.getRequiredProperty("jdbc.prop.prepStmtCacheSqlLimit"));
    HikariDataSource ds = new HikariDataSource(config);
    return ds;
}

How can I use my current configuration to integrate with spring session?

Muhammad Kholid B
  • 478
  • 1
  • 10
  • 25

2 Answers2

5

As I understand spring-session javaconfig-jdbc sample / doc, you "just" need to:

  1. Annotate "your config class" (YourConfig) with org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession.

  2. Name your DataSource "dataSource". (done!;)

  3. Provide a PlatformTransactionManager bean, basing on dataSource in YourConfig.

  4. (in a servlet environment - as yours) Introduce an AbstractHttpSessionApplicationInitializer (in class path) referencing YourConfig:

    public class Initializer extends org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer { // <1>
    
      public Initializer() {
        super(YourConfig.class); // <2>
      }
    }
    

If you wish to install the db schema manually or with an external tool, the SQL scripts are located in spring-session.jar(!org/springframework/session/jdbc/schema-@@platform@@.sql) file or respectively in the source code repository.


These (application.)properties allow further customization:

# Session store type. [jdbc|redis|hazelcast|mongodb]
spring.session.store-type=jdbc
# Session timeout. If a duration suffix is not specified, seconds will be used.
server.servlet.session.timeout= 
# Database schema initialization mode. [alwys | never | embedded]
spring.session.jdbc.initialize-schema=always 
# Path to the SQL file to use to initialize the database schema.(see: https://github.com/spring-projects/spring-session/tree/master/spring-session-jdbc/src/main/resources/org/springframework/session/jdbc)
spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-@@platform@@.sql
# custom spring session table name (see : https://github.com/spring-projects/spring-session/issues/1230) 
spring.session.jdbc.table-name=SPRING_SESSION

  • In the jar/source ditribution, you'll find also "cleanup" (-drop) scripts
  • and the currently provided platforms are:

    db2
    derby
    h2
    hsqldb
    mysql
    oracle
    postgresql
    sqlite
    sqlserver
    sybase
    
xerx593
  • 12,237
  • 5
  • 33
  • 64
  • yeah I missed that part of `Initializer`. But it did not create the table SPRING_SESSION with my current config. How to execute the SQL provided by the spring session? – Muhammad Kholid B Feb 02 '19 at 02:15
  • see edit (5. + 6.)! I think esp. important is 5. and (if you want the session schema initialized by spring boot): `spring.session.jdbc.initialize-schema=always` and `spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-@@platform@@.sql` (where @@platform@@ refers to your database vendor/type). – xerx593 Feb 02 '19 at 14:48
  • 1
    point 5 and 6 are related to spring boot, so I am not using that config. So I run the script for creating the spring session tables with liquibase. – Muhammad Kholid B Feb 02 '19 at 19:15
  • yea, this is an alternative, @MuhammadKholidB, you can find the sql files in the (spring-session) jar, respectively [at github](https://github.com/spring-projects/spring-session/tree/master/spring-session-jdbc/src/main/resources/org/springframework/session/jdbc) – xerx593 Feb 02 '19 at 19:51
  • ...but "5." might still be needed.... and set `initialize-schema=never` (for liquibase) – xerx593 Feb 02 '19 at 19:59
  • 1
    I don't think I need to add settings in my application.properties because it is not a spring boot project. Nothing will read that settings if I add it anyway. – Muhammad Kholid B Feb 02 '19 at 20:14
  • 1
    Can you update your answer so I can mark it as accepted? It needs an update about how to create the tables needed by spring sessions which is my main question here. – Muhammad Kholid B Feb 02 '19 at 20:17
  • avec plaisir! :) – xerx593 Feb 02 '19 at 20:28
  • This link https://github.com/spring-projects/spring-session/blob/master/samples/javaconfig/jdbc/ is dead. is there any other example snippet link available? – Sulthan Feb 28 '20 at 13:55
  • Hi, @Sulthan. This is the current link to the "spring-session-javaconfig-jdbc-sample": https://github.com/spring-projects/spring-session/tree/master/spring-session-samples/spring-session-sample-javaconfig-jdbc ...i also updated in the post;) – xerx593 Feb 28 '20 at 15:05
  • Thanks @xerx593 . But the link is having the example with embedded (H2) database. Is there any example with MySQL or any other database? – Sulthan Feb 29 '20 at 16:10
  • The "only" (2-3) things, that you have to do, to switch this sample from h2 to mysql is: 1. change the h2 dependency to (appropriate) [mysql](https://mvnrepository.com/artifact/mysql/mysql-connector-java) in `.gradle` file. 2. In `Config`class replace the `dataSource` definition with "the one you wish". 3. Delete `H2ConsoleInitializer` class. (please consider that this is a [tag:spring-session] specific sample (see sibling projects)). A mysql-specific spring-boot guide, can be found [here](https://spring.io/guides/gs/accessing-data-mysql/) , this can guide you with step 2. – xerx593 Feb 29 '20 at 20:13
-1
@Autowired
    private Environment env;

@Bean
    public PlatformTransactionManager transactionManager () {

        EntityManagerFactory factory = entityManagerFactory();
        return new JpaTransactionManager(factory);
    }


@Bean
    public EntityManagerFactory entityManagerFactory () {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(Boolean.TRUE);
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.your.domain.project");
        factory.setDataSource(dataSource());
        factory.setJpaProperties(additionalProperties()); // any addtional properties of your ORM
        factory.afterPropertiesSet();
        factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
        return factory.getObject();
    }


@Bean
    public DataSource dataSource () {

        final com.mchange.v2.c3p0.ComboPooledDataSource comboDataSource = new ComboPooledDataSource();

        try {
            comboDataSource.setDriverClass(env.getProperty("jdbc.driver"));
            comboDataSource.setJdbcUrl(env.getProperty("jdbc.url"));
            comboDataSource.setUser(env.getProperty("jdbc.user"));
            comboDataSource.setPassword(env.getProperty("jdbc.properties"));

        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        return comboDataSource;
    }


This will definitely helps you.

Muhammad Waqas
  • 367
  • 3
  • 13