Grails:在域 class 中使用继承进行搜索

Grails: Search with inheritance in domain class

我的 Grails 应用程序中有这两个域模型

class Pet {
    String prop1
    String prop2
}

还有这个

class Cat extends Pet {
    String prop3
    String prop4
}

现在,在我的应用程序中,我有许多 类 正在扩展 Pets,我想使用条件搜索 Pet,指定一些其他宠物中不存在的属性。

我怎样才能使这个操作成为可能?如果我尝试进行搜索,当结果不包含 属性 时,引发异常。

我认为,你正在尝试的事情是不可能的。但是您可以使用两个查询来实现它:

首先做一个较低级别的查询:

// Inject the bean
def sessionFactory

String statement = "select id from pet where prop1 = 'foo' or prop3 = 'bar'";
def session = sessionFactory.getCurrentSession()
def queryResult = session.createSQLQuery(statement)

由于父 class Pet 将拥有所有字段,因此对任何字段进行上述较低级别的查询都可以。

现在,使用 id 获取域实例:

def pets = Pet.getAll(queryResult)

由于 object-oriented 编程的工作方式,您尝试做的事情是不可能的。

class Foo { }
class Bar extends Foo { }

在此示例中,Bar 的实例也是 Foo。但是,Foo 的实例不是 Bar。换句话说,super-class 不知道 它的子类类,而子类 知道 它的子类super-class.

回到您的示例,您无法从 Pet 访问 prop3prop4,因为它们不是 Pet 属性。

正在努力寻找解决方案

考虑到您的 类,我同意 Shashank Agrawal 的解决方案。 SQL(不是 HQL 或任何其他 GORM 查询)是通过查询 pet table 访问所有属性(实际上是列)的唯一方法。当然,这假定您使用默认的 table-per-hierarchy 继承。它不适用于 table-per-subclass 继承。

鉴于 table-per-hierarchy 的假设意味着您已经在所有 Pet 的子 类 中接受可为 null 的属性。这是一个要求。所以,你能做的是

  1. 弃子类
  2. 将所有属性放入 Pet
  3. Pet中添加属性以指定宠物类型。

请注意,这基本上是 table-per-hierarchy 在数据库级别所做的。区别在于它不是继承,这使得所有属性都可以从 Pet.

def pets = Pet.withCriteria { eq('prop3', 'whatever') }