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

时间:2013-04-16 10:28:06

标签: grails gorm

当我想保存我的对象时,我有这个问题

我的客户

String firstName
String lastName
LocalDate dateOfBirth
CountryCode nationality

我的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
  }
}

当我尝试保存我的对象时,我收到此错误

  

类       org.hibernate.TransientObjectException   信息       object引用未保存的瞬态实例 - 在刷新之前保存瞬态实例:lookup.iso.CountryCode

你有想法如何解决这个问题吗?

Thankx

2 个答案:

答案 0 :(得分:2)

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

在分别将hasOne或belongsTo分别添加到Customer和CountryCode之前,您可能需要考虑如何使用CountryCode。 CountryCode用作:

  1. 一对多查找/引用/字典实体,其中许多客户可能映射到特定的CountryCode
  2. 一对一的唯一实体,其中每个客户都有一个唯一的CountryCode
  3. 要实施#1,您应该使用CountryCode WITHOUT a belongsTo中的hasOne定义一个单向关系,如下所示:

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

    这将在引用特定CountryCode的Customer表上创建一个外键 - 基本上是一对多。

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

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

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

答案 1 :(得分:2)

使用Grails关系约定

static hasOne = [nationality:CountryCode]

在客户类和

static belongsTo = [customer:Customer]
在CountryCode类

检查grails docs,尤其是关于级联保存的段落。 如果这不适合您的情况,则需要在将CountryCode实例分配给Customer实例之前调用save()。

如果适用于您的情况,您还可以使用 static embedded

如果您将CountryCode视为字典实体,那么在将其分配给Customer实例之前从存储库加载所需的ContryCode实例是另一回事。