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

Grails 6.1.2中UserRole表未填充问题的原因排查与解决求助

Grails 6.1.2 Spring Security UserRole关联表为空问题排查与修复

问题背景

开发Grails 6.1.2应用,已安装Spring Security Core插件并完成配置,使用MySQL数据库。通过Bootstrap.groovy初始化用户、角色及关联关系时,User和Role表数据正常填充,但UserRole关联表始终为空,清理构建应用后问题仍存在。

可能原因及修复方案

1. 数据未刷新到数据库

默认情况下UserRole.create方法的flush参数为false,Hibernate会将数据暂存在缓存中,未立即写入数据库。

修复:
调用UserRole.create时显式传入flush: true,强制将缓存数据刷入数据库;或在Bootstrap代码末尾添加sessionFactory.currentSession.flush()手动刷新会话。

2. 保存失败未抛出异常

自动生成的UserRole.create方法中,save()未启用failOnError: true,当关联关系保存失败(如重复创建)时会静默失败,无异常抛出。

修复:
修改UserRole.create方法,给save()添加failOnError: true,确保保存失败时抛出异常,便于排查问题:

static UserRole create(User user, Role role, boolean flush = false) {
    def instance = new UserRole(user: user, role: role)
    instance.save(flush: flush, failOnError: true)
    instance
}

3. 重复创建关联关系

如果之前运行过Bootstrap,User与Role的关联可能已存在,再次创建会因复合主键约束导致保存失败。

修复:
创建关联前先通过UserRole.exists()判断关系是否已存在,避免重复操作:

if (!UserRole.exists(user.id, userRole.id)) {
    UserRole.create(user, userRole, true)
}

修改后的Bootstrap完整代码

def userRole = Role.findByAuthority("ROLE_USER") ?: new Role(authority: "ROLE_USER").save(failOnError: true)
def superAdminRole = Role.findByAuthority("ROLE_SUPERADMIN") ?: new Role(authority: "ROLE_SUPERADMIN").save(failOnError: true)
// 先查询用户是否已存在,避免重复创建
def user = User.findByUsername("user") ?: new User("user", "1").save(failOnError: true)
def superAdmin = User.findByUsername("admin") ?: new User("admin", "2").save(failOnError: true)

try {
    log.info('Creating user roles...')
    if (!UserRole.exists(user.id, userRole.id)) {
        UserRole.create(user, userRole, true)
    }
    if (!UserRole.exists(superAdmin.id, superAdminRole.id)) {
        UserRole.create(superAdmin, superAdminRole, true)
    }
    log.info('User roles created successfully')
} catch (Exception e) {
    log.error('Error creating user roles:', e)
    // 捕获验证异常,打印详细错误信息
    if (e instanceof ValidationException) {
        log.error("Validation errors: ${e.errors}")
    }
}

额外排查步骤

  • 查看应用日志,特别是错误日志,确认是否有UserRole保存时的异常信息;
  • 检查数据库中User和Role的记录ID,确保关联的ID存在且有效;
  • 确认UserRole域类的复合主键配置正确,自动生成的类应包含以下映射:
static mapping = {
    id composite: ['user', 'role']
    version false
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:37:40