You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Grails3集成Spring Session JDBC时无法获取SessionRepository

Grails 3.3.15集成Spring Session JDBC到PostgreSQL启动报错BeanCreationException

背景

尝试在Grails 3.3.15应用中通过Spring Session JDBC将HttpSession持久化到PostgreSQL,参考官方Redis实现指南(无JDBC相关指南)后做了以下配置:

已完成的配置

  1. build.gradle添加依赖:
compile "org.springframework.session:spring-session-jdbc"
compile 'org.springframework.boot:spring-boot-starter-data-jpa'
  1. application.groovy配置数据源:
spring.datasource.url=System.getenv("DB_URL")
spring.datasource.username=System.getenv("DB_USERNAME")
spring.datasource.password=System.getenv("DB_PASSWORD")
  1. application.yml配置Spring Session:
spring:
  session:
    store-type: "jdbc"
    table-name: "SPRING_SESSION"

启动错误

启动应用时触发BeanCreationException,异常栈如下:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.session.SessionAutoConfiguration$SessionRepositoryValidator': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No session repository could be auto-configured, check your configuration (session store type is 'jdbc')
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:407)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1622)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:123)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:666)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:353)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:300)
    at grails.boot.GrailsApp.run(GrailsApp.groovy:84)
    at grails.boot.GrailsApp.run(GrailsApp.groovy:393)
    at grails.boot.GrailsApp.run(GrailsApp.groovy:380)
    at grails.boot.GrailsApp$run.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:136)
    at com.foo.bar.Application.main(Application.groovy:8)

排查结果

调试发现org.springframework.boot.autoconfigure.session.SessionRepositoryValidator的checkSessionRepository()方法中,sessionRepositoryProvider.getIfAvailable()返回null,导致抛出IllegalArgumentException,说明SessionRepository未被正确配置。


解决方案

1. 修正依赖版本与完整性

Grails 3.3.15对应的Spring Boot版本是1.5.x,需确保Spring Session JDBC版本与Spring Boot兼容(1.5.x对应Spring Session JDBC 1.3.x版本),同时添加Spring JDBC依赖(Spring Session JDBC依赖Spring JDBC而非仅JPA):
修改build.gradle:

compile "org.springframework.session:spring-session-jdbc:1.3.5.RELEASE"
compile 'org.springframework.boot:spring-boot-starter-jdbc'
compile 'org.springframework.boot:spring-boot-starter-data-jpa' // 保留JPA依赖(如果业务需要)

2. 手动配置SessionRepository Bean

由于Grails自动配置未触发Spring Session JDBC的自动配置,需手动创建JdbcOperationsSessionRepository Bean:
在grails-app/conf/spring/resources.groovy中添加:

import org.springframework.session.jdbc.JdbcOperationsSessionRepository
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession

beans = {
    jdbcOperationsSessionRepository(JdbcOperationsSessionRepository, ref('dataSource'), ref('transactionManager')) {
        tableName = 'SPRING_SESSION'
    }
}

// 启用Spring Session JDBC
@EnableJdbcHttpSession(tableName = "SPRING_SESSION")
class SpringSessionConfig {
}

3. 创建Spring Session所需数据库表

Spring Session JDBC需要特定表结构,执行以下PostgreSQL脚本创建表:

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)
);

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 BYTEA 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
);

CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);

4. 补全数据源驱动配置

在application.groovy中添加PostgreSQL驱动类配置:

spring.datasource.driverClassName = 'org.postgresql.Driver'

内容的提问来源于stack exchange,提问作者Manish Kapoor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 12:59:13