交叉依赖关系问题:对象引用未保存的瞬态实例,在刷新之前保存瞬态实例



似乎这个问题被问了一遍又一遍,我仍然没有找到一个答案来解决我的。下面是一个域模型。我需要为每一个新创建或更新Sec用户确保它有一个配置文件,如果没有,然后创建一个新的并分配给它。

配置文件同样需要-每次保存期间检查它是否有工作空间,如果没有则创建一个。这样做是为了确保所有Sec用户至少有一个工作区。除了所有者自己,一个工作区可能有不同的贡献者。

当我试图保存Sec User时,我总是得到:

object references an unsaved transient instance save the transient instance before flushing
总的来说,我确实理解问题的本质。在构造函数中传递的实例没有持久化,因此没有id。我仍然不知道如何强制这3个插入成为单个事务的一部分,并正确处理引用。
class SecUser implements Serializable {
    String email
    static hasOne = [profile: Profile]
    def beforeValidate() {
        if (profile == null) {
            profile = new Profile(secUser: this)
        }
        profile.validate()
    }
}
class Profile {
    static belongsTo = [secUser: SecUser]
    static hasMany = [workspaces: Workspace]
    static constraints = {
        workspaces minSize: 1
    }
    def beforeValidate() {
        if (workspaces == null || workspaces.isEmpty()) {
            def workspace = new Workspace(owner: this).save()
            workspaces = [workspace]
        }
    }
}
class Workspace {
    String title = "Workspace ${10000 + new Random().nextInt(89999)}"
    static hasOne = [owner: Profile]
    static belongsTo = Profile
    static hasMany = [contributors: Profile]
}

更新1

我已经替换了

workspaces = [workspace]

this.addToWorkspaces(workspace)

现在我得到了这个:

错误spi。SqlExceptionHelper—引用完整性约束违规:"FK_MYFCABJIQ83AG2CLBDF61MPA5: PUBLIC。PROFILE_WORKSPACES外键(workspace_id)引用public.workspace (id) (0)";SQL语句:insert into profile_workspace (profile_id, owner_id)值(?, ?) [23506-176].

生成了一个新的连接表,它有3列。我看到它试图做错误的插入。应该插入owner_id, workspace_id (profile_id应为空)

当我处理涉及多个域对象的业务事务时,我创建了一个Grails服务。使用服务可以简化域单元测试,还有助于描述代码要完成的任务。可以把它看作事务脚本设计模式(Gang of Four)。

你的服务可以有create()和update()方法,然后你可以从控制器调用它们。然后,您的服务将根据需要连接SecUser、Profile和Workspace。

最新更新