【问题标题】:Grails domains inheriting abstract classes hasMany继承抽象类的 Grails 域 hasMany
【发布时间】:2013-09-26 19:07:57
【问题描述】:

所以我试图让 2 个域从一个域继承。

abstract class Pet {
    Nose nose
    static hasMany = [legs: Leg]
}

class Dog extends Pet {
    static hasMany = [friends: Friend]
}

我得到一个错误:

Caused by: org.codehaus.groovy.grails.exceptions.InvalidPropertyException: No property found for name [legs] for class [class animals.Dog]

有什么想法吗?我需要做些什么来结合 hasManys 吗?

【问题讨论】:

  • 您使用的是什么版本的 Grails 以及 Pet 类在哪里定义(例如 src/groovy 或 grails-app/domain)?
  • 2.2.4 和 Pet 定义在 src/groovy

标签: grails inheritance abstract grails-domain-class


【解决方案1】:

我尝试复制问题,但没有得到InvalidPropertyException,但生成的数据库架构缺少DogLeg 之间的1:m 关系。

我相信这个问题与Pet 是一个抽象类有关。如果Dog类从Pet继承Set legs,那么为了将Leg实例持久化到数据库,底层Leg表需要有一个外键pet_id**。由于Petabstract 类,因此没有为其创建表,因此没有id 列。因此,不能在依赖类Leg 中创建外键。

使Pet 类成为具体类(将其移动到grails-app/domain 并删除abstract 关键字),意味着将创建一个带有id 字段的表。在Leg 表中,可以/将创建一个pet_id 列,Hibernate 将使用它来持久化/检索Set legs

**(或关联实体表,例如pet_legs,需要有外键)

但是,使Pet 类具体化,将导致Pet 的所有子类都存储到该表中,因此如果您希望每个子类都有自己的表,您可以添加:

  static mapping = {
    tablePerHierarchy false
  }

Dog 类,它将在数据库中创建PetDog 等表。

【讨论】:

  • 我从不想将pet_id 字段用作外键,我只想让Dog 继承Pet 的属性。
  • 抱歉,我最初的答案可能有点神秘,所以我对其进行了扩展以解释pet_id 问题的含义。
【解决方案2】:

你错过了几件事:

  1. GORM 不会为 abstract 类生成表关系
  2. static fields/methods are not inherited. They belong to the class, not to the object references

所以你必须将代码更改为以下之一:

abstract class Pet {
    Nose nose
}

class Dog extends Pet {
    static hasMany = [legs: Leg, friends: Friend]
}

abstract class Pet {
    Nose nose
    static hasMany = [legs: Leg]
}

class Dog extends Pet {
    static hasMany = [friends: Friend] + Pet.hasMany
}

是的,第二种方法有效,因为您可以通过另一个静态类的静态成员来初始化一个类的静态成员

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多