Grails对象引用了一个未保存的瞬态实例

Grails对象引用了一个未保存的瞬态实例,grails,gorm,Grails,Gorm,当我想保存我的对象时,我遇到了这个问题 我的顾客 String firstName String lastName LocalDate dateOfBirth CountryCode nationality 我的国家代码 @Audited class CountryCode implements Serializable { String code String symbolA2 String symbolA3 String countryName static c

当我想保存我的对象时,我遇到了这个问题

我的顾客

String firstName
String lastName
LocalDate dateOfBirth
CountryCode nationality
我的国家代码

  @Audited
class CountryCode implements Serializable {

  String code
  String symbolA2
  String symbolA3
  String countryName

  static constraints = {
    code size:3..3, unique: true, matches: '[0-9]+'
    symbolA2 size:2..2, nullable: false, unique: true, matches: '[A-Z]+'
    symbolA3 size:3..3, nullable: false, unique: true, matches: '[A-Z]+'
    countryName size:1..50
  }

  static mapping = {
    id generator: 'assigned', name: 'code'
  }

  def beforeValidate() {
    symbolA2 = symbolA2?.toUpperCase()
    symbolA3 = symbolA3?.toUpperCase()
  }

  @Override
  String toString() {
    return countryName
  }
}
当我试图保存我的对象时,我收到了这个错误

阶级 org.hibernate.transientObject异常 消息 对象引用未保存的临时实例-在刷新之前保存临时实例:lookup.iso.CountryCode

  @Audited
class CountryCode implements Serializable {

  String code
  String symbolA2
  String symbolA3
  String countryName

  static constraints = {
    code size:3..3, unique: true, matches: '[0-9]+'
    symbolA2 size:2..2, nullable: false, unique: true, matches: '[A-Z]+'
    symbolA3 size:3..3, nullable: false, unique: true, matches: '[A-Z]+'
    countryName size:1..50
  }

  static mapping = {
    id generator: 'assigned', name: 'code'
  }

  def beforeValidate() {
    symbolA2 = symbolA2?.toUpperCase()
    symbolA3 = symbolA3?.toUpperCase()
  }

  @Override
  String toString() {
    return countryName
  }
}
你有办法解决这个问题吗


Thankx

导致错误的具体原因是,在将CountryCode分配给客户之前,您没有保存CountryCode,因此Hibernate(Grails的底层ORM)认为它是暂时的。基本上,您没有定义任何GORM关系(例如,has*,belongsTo)。通过定义GORM关系,您可以根据关系的定义方式进行级联保存/删除

<>在简单地添加HasOne或归属于客户和国家代码之前,您可能需要考虑如何使用国家代码。CountryCode是否用作:

  • 一对多查找/引用/字典实体,其中许多客户可能映射到特定的国家代码
  • 一对一唯一实体,每个客户都有唯一的国家代码
  • 要实现#1,您应该在CountryCode中使用
    belongsTo
    定义单向关系,而在Customer中不使用
    hasOne
    ,如下所示:

    class CountryCode {
      static belongsTo = [customer: Customer]
      ...
    }
    
    class Customer {
      static hasOne = [country: CountryCode]
      ..
    }
    class CountryCode {
      static belongsTo = [customer: Customer]
      ..
    }
    
    这将在Customer表上创建一个外键,引用特定的CountryCode(基本上是一对多)

    要实施#2,您应该使用CountryCode中的
    belongsTo
    和客户中的a
    hasOne
    来定义双向关系,如下所示:

    class CountryCode {
      static belongsTo = [customer: Customer]
      ...
    }
    
    class Customer {
      static hasOne = [country: CountryCode]
      ..
    }
    class CountryCode {
      static belongsTo = [customer: Customer]
      ..
    }
    

    这将在CountryCode表上创建一个外键返回给特定客户-基本上是一对一的映射。

    使用Grails关系约定

    static hasOne = [nationality:CountryCode]
    
    在客户级别和

    static belongsTo = [customer:Customer]
    
    在CountryCode类

    检查一下,特别是关于级联保存的段落。 如果这不适合您的情况,则需要在将CountryCode实例分配给客户实例之前调用save()

    如果适用于您的案例,您也可以使用


    另外一件事,如果您将CountryCode视为字典实体,然后在将其分配给客户实例之前从库中加载所需的Rebug代码实例。

    您可以在实际执行保存时添加代码的相关部分吗?这是一个很好的解释和解决方案,在我的例子中,“CountryCode”可以是,也可以不是。