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

时间:2015-08-13 05:21:49

标签: hibernate grails gorm

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

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

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

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   FOREIGN KEY(WORKSPACE_ID)参考PUBLIC.WORKSPACE(ID)(0)“; SQL   声明:插入profile_workspaces(profile_id,owner_id)   值(?,?)[23506-176]。

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

1 个答案:

答案 0 :(得分:0)

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

您的服务可以使用create()和update()方法,然后您可以从控制器中调用这些方法。然后,您的服务将根据您的需要连接SecUser,Profile和Workspace。