【问题标题】:Grails - How do I get the value of a domain entity prop in a function of its parent classGrails - 如何在其父类的函数中获取域实体道具的值
【发布时间】:2015-12-23 21:23:01
【问题描述】:

我在一个 groovy 文件中有一个抽象类:

实施 1

public abstract class Item {
  public String testStr;

  public String getBigTestStr(){
      String s = "___" + this.testStr;
      return s;
  }
}

继承自

class Material extends Item {
  public String testStr;

  static marshalling = {
    detail {
        includes "bigTestStr"
    }
    summary {
        includes "bigTestStr"
    }
  }

  static mapping = {
    table   'materialset'
    id       column: 'NODEID'
    testStr  column: 'MATERIALTYPE'
    version  false
  }
}

这个想法是点击材质的端点将返回Item.bigTestStr()的返回值。但是,当我通过Item.bigTestStr() 进行跟踪时,调试的变量表显示this.testStr 的值,但当它添加到s 时为空。见这里:

我尝试从Material 中取出testStr 属性

实施 2

class Material extends Item {

  static marshalling = {
    detail {
        includes "bigTestStr"
    }
    summary {
        includes "bigTestStr"
    }
  }

  static mapping = {
    table   'materialset'
    id       column: 'NODEID'
    testStr  column: 'MATERIALTYPE'
    version  false
  }
}

但我仍然遇到同样的问题。

对于这两种实现,端点都返回

{
  bigTestStr: ____null
}

如何获取Material.testStr 的实际值以供其父类中的函数使用?

更新

正如 Emmanuel 指出的,实现 2 是使用父类属性的正确方法。但是,此实现似乎不适用于将父类的属性映射到数据库列。所以真正的问题是:如何让Material.testStr 映射到数据库列?

【问题讨论】:

  • 顺便说一下 Grails 版本 2.3.8。

标签: grails grails-orm grails-2.0 grails-domain-class


【解决方案1】:

看起来您的问题在于您如何初始化 Material 实例。这是一个例子:

public abstract class Item {
  public String testStr

  public String getBigTestStr(){
      "___$testStr"
  }
}

class MaterialA extends Item {
  public String testStr

  static marshalling = {
    detail {
        includes 'bigTestStr'
    }
    summary {
        includes 'bigTestStr'
    }
  }

  static mapping = {
    table   'materialset'
    id       column: 'NODEID'
    testStr  column: 'MATERIALTYPE'
    version  false
  }
}

class MaterialB extends Item {

  static marshalling = {
    detail {
        includes 'bigTestStr'
    }
    summary {
        includes 'bigTestStr'
    }
  }

  static mapping = {
    table   'materialset'
    id       column: 'NODEID'
    testStr  column: 'MATERIALTYPE'
    version  false
  }
}

上面显示了三个类ItemMaterialAMaterialB。这两个材料类模拟了您的两个测试:MaterialA 有一个testStr 属性,而MaterialB 则从Item 继承了一个同名的属性。以下是初始化两个类的实例并测试 getBigTestStr() 时发生的情况:

new MaterialA(testStr: 'Hello').with {
    assert bigTestStr == '___null'
}

new MaterialB(testStr: 'Hello').with {
    assert bigTestStr == '___Hello'
}

简而言之,您的第二种方法(继承该属性)有效。超类没有(也不应该)访问其子类中的任何内容。它甚至不知道它的子类。该方法有效,因为在 MaterialB 的实例中初始化 testStr 实际上会初始化从 Item 继承的属性;当然可以在 Item 类中访问。

就您而言,Grails 正在使用存储在数据库中的值为您初始化实例。所以我会检查你的数据库。

更新

这是一个使用特征而不是抽象类的示例:

public trait Item {
  String testStr

  public String getBigTestStr(){
      "___$testStr"
  }
}

class Material implements Item {

  static marshalling = {
    detail {
        includes 'bigTestStr'
    }
    summary {
        includes 'bigTestStr'
    }
  }

  static mapping = {
    table   'materialset'
    id       column: 'NODEID'
    testStr  column: 'MATERIALTYPE'
    version  false
  }
}

new Material(testStr: 'Hello').with {
    assert bigTestStr == '___Hello'
}

这样就不需要Item 表了。

【讨论】:

  • 我能够在Material 的构造函数中设置testStr 的值,所以你说得对,我的问题肯定与数据库有关。 MaterialType 列肯定填充在每一行中。我想我真正的问题是将列中的值映射到testStr 似乎不起作用。我必须在Item 中做任何事情来映射该属性吗?我不能将它直接映射到表,因为其他子类将使用不同的表。
  • 默认情况下,当您从域类中删除一个属性时,它的数据库列不会被删除。当Material 有一个testStr 属性时,数据库中有两个test_str 列:一个在item 表中,另一个在material 表中。如果您随后填充了数据库,然后从Material 中删除了testStr,那么您仍然拥有test_str 两列,但material 表中的那一列将被忽略。如果是这种情况,您可以通过数据库查询将material.test_str 复制到 item.test_str 来修复它。然后删除material.test_str 列。
  • 请注意,即使您的 Item 示例表明您正在使用每个层次结构的表,我也会按照您所说的为每个子类设置一个表;意味着超类和它的子类共享同一个表。
  • 也许我正在尝试做一些不完全是 grails 设计的事情。我根本没有使用 GORM 来创建表。此外,数据库中没有Item 表,也不应该有。我想要它的唯一原因是我不必在item 的每个子类上管理相同的属性和函数。
  • 如果您想重用属性和方法,一个很好的方法是使用 Groovy 特征。但是,您需要 Grails 2.4 或更高版本。如果您将Item 设为特征,则它不再是域类并且不需要表。这也意味着 Item.groovy 必须从 grails-app/domains/... 移动到 src/main/groovy/...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多