似乎一遍又一遍地问这个问题我仍然找不到解决我的问题的答案。我在下面有一个域名模型。我需要为每个新创建或更新的用户确保它有一个配置文件,如果没有,则创建一个新配置文件并分配给它。
配置文件所需的相同 - 每次在保存期间检查它是否有工作空间,如果没有,则创建一个。这样做是为了确保所有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应为空)
答案 0 :(得分:0)
当我处理涉及多个域对象的业务事务时,我创建了一个Grails服务。使用服务可以简化域单元测试,还可以帮助描述代码尝试完成的任务。可以将其视为事务脚本设计模式(Gang of Four)。
您的服务可以使用create()和update()方法,然后您可以从控制器中调用这些方法。然后,您的服务将根据您的需要连接SecUser,Profile和Workspace。