4

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

我的客户

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.TransientObjectException 消息对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例:lookup.iso.CountryCode

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

谢谢

4

2 回答 2

2

使用 Grails 关系约定

static hasOne = [nationality:CountryCode]

在客户类和

static belongsTo = [customer:Customer]

在 CountryCode 类

检查grails 文档,特别是关于级联保存的段落。如果这不适合您的情况,那么您需要先在 CountryCode 实例上调用 save() ,然后再将其分配给 Customer 实例。

如果适用于您的情况,您也可以使用静态嵌入。

如果您将 CountryCode 视为字典实体,则另一件事是从存储库加载所需的 ContryCode 实例,然后再将其分配给 Customer 实例。

于 2013-04-16T13:42:32.820 回答
2

您的错误的具体原因是因为您在将 CountryCode 分配给客户之前没有保存它,所以 Hibernate(Grails 的底层 ORM)认为它是暂时的。基本上,您没有定义任何 GORM 关系(例如,has*、belongsTo)。通过定义 GORM 关系,您可以获得级联保存/删除的能力,具体取决于关系的定义方式。

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

  1. 一对多的查找/参考/字典实体,其中许多客户可以映射到特定的 CountryCode
  2. 一对一的唯一实体,每个客户都有一个唯一的 CountryCode

belongsTo要实现#1,您应该在 CountryCode中使用没有hasOne在 Customer中定义一个单向关系,如下所示:

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

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

belongsTo要实现 #2,您应该在 CountryCode中使用与hasOne在 Customer 中的 a 来定义双向关系,如下所示:

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

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

于 2013-04-16T13:37:43.013 回答