考虑以下域类

class Person {

    String fullName

    static hasMany = [
            emails: EmailAddress
    ]

    EmailAddress defaultEmailAddress
}

及其对应的
class EmailAddress {

    String email

    static belongsTo = [person: Person]

    static constraints = {
        email( unique:true, email:true )
    }
}

在我看来,这是给定人员设置其首选电子邮件地址的最佳方法。另一个明显的选择是在EmailAddress中有一个标志,指示它是否是首选标志。但是,通过此人直接引用其首选的EmailAddress,我可以保证在任何给定时间只有一个EmailAddress是首选​​地址,而且我猜它的效果更好。

问题是由于此defaultEmailAddress而使我不断收到TransientPropertyValueException,如果删除此属性,则它运行得很好。

这是我用于设置和保存新Person对象的代码
/*
  Comes from a submitted form containing (I can't use less than and greater than in SO so I used parenthesis...).
  (input type="text" name="fullName" value="Full Name" /)
  (input type="text" name="emails[0].email" value="[email protected]" /)
*/
Person person = new Person( params );
person.defaultEmailAddress = person.emails[0];
person.save( flush:true );

我认为由于从defaultEmailAddress到Person的反向引用,我得到了TransientPropertyValueException,当构造Person时grails自动为person.emails [0]定义了反向引用,但是当我显式设置时
person.defaultEmailAddress = person.emails[0];

那么它就不能用于反向引用,并提供以下输出:
2015-09-18 18:54:36,858 [http-bio-8080-exec-8] ERROR errors.GrailsExceptionResolver  - TransientPropertyValueException occurred when processing request
Not-null property references a transient value - transient instance must be saved before current operation : sos.Person.defaultEmailAddress -> sos.EmailAddress. Stacktrace follows:
Message: Not-null property references a transient value - transient instance must be saved before current operation : sos.Person.defaultEmailAddress -> sos.EmailAddress

难道我做错了什么?这是Hibernate的错误吗?请帮忙。

最佳答案

我将defaultEmailAddress定义为hasOne(请参阅ref-doc):

static hasOne = [ defaultEmailAddress:EmailAddress ]

10-08 15:27