【问题标题】:GORM: Save transient object before flushingGORM:在刷新之前保存瞬态对象
【发布时间】:2012-05-06 16:56:06
【问题描述】:

我正在将 SpringSecurity 插件与应用程序集成。为此,我安装了插件并运行了 s2-quickstart 脚本,该脚本创建了三个域类:SecUserSecRoleSecUserSecRole 以及登录/注销控制器。

由于我已经有一个现有的用户域类并想保留它,我修改了用户以扩展 SecUser 并从用户中删除了用户名和密码的重叠字段。此外,我已将 tablePerHierarchy false 添加到 User 和 SecUser 映射部分。

在 BootStrap 中,我正在尝试创建一个管理员用户以在启动时存在。为此,我创建了一个新的SecRole 对象adminRole,其权限设置为ROLE_ADMIN。然后,我创建一个新的用户对象并通过

检查它是否包含管理员角色
def springSecurityService
def init {
    def adminUser = User.findByUsername('admin') ?: new User(
        username:'admin',
        password:'adminUser',
        userType:'Admin',
        enabled:true    
    ).save(failOnError:true)

    if (!adminUser.authorities.contains(adminRole))
        SecUserSecRole.create adminUser, adminRole, true

}

我的问题是,无论 adminUser 是否被声明为 User 或 SecUser 实例,我都会不断收到临时实例异常。由于 userType 有一个空白约束:false,如果我在创建用户实例时注释掉 userType 字段,我会得到一个异常,指出 null 不是 userType 的有效设置。当我包含它时,我得到了瞬态对象异常:对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例:books4africa.SecUser,所以我知道我正在通过所有用户验证设置。

什么原因导致在这种情况下无法保存有效的用户对象?

编辑

此问题的解决方案是删除现有的开发数据库文件并重新初始化应用程序。我的猜测是 db 和 Spring Security 与原始 db 之间存在某种冲突,因此使用新的 db 重新启动应用程序解决了问题。

由于以下答案都没有解决确切的问题,因此我不会接受这种情况,但感谢您的帮助!

【问题讨论】:

  • 您是否尝试将 flush:true 添加到保存调用中?使其 .save(failOnError:true, flush:true)
  • 在 Grails 2.0+ 中,还有 findOrSaveWhere 方法可以检索指定对象或创建一个新对象。
  • 大多数时候,当我看到该异常时,它与.save(failOnError:true, flush:true) 或类似的东西无关。好吧,当您使用基于框架构建的框架时,这就是问题所在,有时异常只会告诉您最低限度。

标签: grails grails-orm transient


【解决方案1】:

您没有说瞬态实例是什么类型(用户或角色)。当您创建管理员角色时,您是否在尝试为新管理员用户提供此角色之前保存它?我在上面的代码中没有看到那部分。

【讨论】:

  • 我修改了我的问题以包含异常消息。它的 SecUser 对象给我带来了麻烦。奇怪的是,我为我自己开发的另一个 Web 应用程序执行了完全相同的过程,尽管域映射要复杂得多,但它第一次运行没有问题。
【解决方案2】:

对我来说,这似乎是域或创建它们实例的方式的问题。

你说:

我修改了 User 以扩展 SecUser 并删除了重叠字段 来自用户的用户名和密码。另外,我添加了 tablePerHierarchy 对 User 和 SecUser 映射部分都为 false。

但也许你没有告诉插件你这样做了。请查看documentation regarding the domain classes。要使用您自己的域,您必须配置 SpringSecurity 插件(文档包含您需要的所有信息)。因此,例如,如果您想使用自己的 user 类。你把这样的东西放在你的配置上:

grails.plugins.springsecurity.userLookup.userDomainClassName = 'your.package.NameOfYourClass'

这将告诉插件它必须为用户使用的类是NameOfYourClass

使用默认类很重要,例如生成的快速入门是正确使用自定义用户和角色类的最简单方法(只需将每个属性复制到您自己的类中,并根据需要重命名) .

还可以查看tutorials,了解如何正确保存用户和角色。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 2015-09-27
    • 2021-03-03
    • 2013-11-30
    • 2017-04-12
    • 1970-01-01
    相关资源
    最近更新 更多