Grails 圣杯,戈姆,关系。可选子记录

Grails 圣杯,戈姆,关系。可选子记录,grails,gorm,Grails,Gorm,例如,我有一个父类Cafee: class Cafee { String name static hasMany = [ admin: Person ] } 和一个儿童班的人: class Person { String name static belongsTo = [cafee: Cafee] } 我用以下方法对Cafee做了一些记录: def user = new Person(name: "Andrew") d

例如,我有一个父类Cafee:

class Cafee {    
    String name
    static hasMany = [
         admin: Person
    ]
}
和一个儿童班的人:

class Person {    
    String name
    static belongsTo = [cafee: Cafee]
}
我用以下方法对Cafee做了一些记录:

def user = new Person(name: "Andrew")
def a = new Cafee(name: "Tarelka")
             .addToAdmin(user)
             .save()
将子对象添加到父对象很好,但当我尝试单独创建Person实例时,例如:

def visitor = new Person(username: 'testerUser', password:'password', firstName:'Иван', lastName:'Иванов', email:'ivanov@gmail.com', isAdminCafee: false)
         visitor.save(flush:true)
我得到一个错误:

ERROR context.GrailsContextLoaderListener  - Error initializing the application: object references an unsaved transient instance - save the transient instance before flushing: restorator.auth.Person; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: restorator.auth.Person
Message: object references an unsaved transient instance - save the transient instance before flushing: restorator.auth.Person; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: restorator.auth.Person

如何修复它?

这里发生的两件事并不完全显而易见。一是这种形式的
属于

static belongsTo = [cafee: Cafee]
是双向的,与

static belongsTo = [Cafee]
这是无方向的;在这两种变体中,
Cafee
可以通过其
admin
集合访问其关联的
Person
实例,但使用第二种语法,
Person
无法直接知道它与哪个
Cafee
关联

像您那样声明一个
hasMany
将在类中创建一个
Person
s的
集合,其名称是您在
hasMany
映射中使用的键,在本例中为
admin
;好像你加了

Set<Person> admin
类中添加了一个名为
Cafee
Cafee
类型的字段。好像你加了

Cafee cafee
但同样,请不要手动添加,只是要知道它们在那里

因此,问题在于,除非您使用
null:true
重写,否则持久属性在默认情况下不会为null,因此,如果您打印出该
Person
实例的错误,您会看到至少一个实例抱怨不可为null的
cafee
属性为null。这适用于
addToAdmin
,因为该方法做了很多工作。如果将集合实例化为一个新的
集合
接口实现(可能只是一个
哈希集
),如果它为null(只有在域类实例为新实例时才会出现;持久集合永远不会为null,只是空的或包含项),则将
Person
添加到集合中,最后,如果关系是双向的,它将
个人
上的反向引用设置为所属的
Cafee

因此,您所缺少的就是手动设置
Cafee
,或者将其作为映射构造函数的一部分

user = new Person(cafee: a, username: 'testerUser', ...)
或稍后在工作流中(但在验证或保存之前)


Person
域中尝试将
cafee
设置为可选<代码>cafee nullable:true
谢谢,我已经在cafee类中添加了约束cafee nullable:true。一切顺利。
user = new Person(cafee: a, username: 'testerUser', ...)
user = new Person(username: 'testerUser', ...)
...
user.cafee = a
...
user.save()