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
相关产品推荐
相关产品推荐

