【问题标题】:Grails: Search with inheritance in domain classGrails:在域类中使用继承进行搜索
【发布时间】:2016-01-18 17:20:21
【问题描述】:

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

class Pet {
    String prop1
    String prop2
}

还有这个

class Cat extends Pet {
    String prop3
    String prop4
}

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

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

【问题讨论】:

  • 对不起。我纠正了。谢谢沙申克。你能回答这个问题吗?

标签: grails grails-orm hibernate-criteria


【解决方案1】:

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

先做一个低级查询:

// 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)

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

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

def pets = Pet.getAll(queryResult)

【讨论】:

  • 不,因为我需要从 Pet 中进行搜索(使用条件)。我有很多宠物(猴子、海豚、狗等)。如果我尝试使用特定宠物的属性进行搜索,当查询返回没有此属性的对象时,操作失败...
【解决方案2】:

由于面向对象编程的工作原理,您尝试做的事情是不可能的。

class Foo { }
class Bar extends Foo { }

在这个例子中,Bar 的实例也是一个 Foo。但是,Foo 的实例 不是 Bar。换句话说,一个超类知道关于它的子类的任何事情,而一个子类知道它的超类。

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

努力寻找解决方案

考虑到您的课程,我同意 Shashank Agrawal 的解决方案。 SQL(不是 HQL 或任何其他 GORM 查询)是通过查询 pet 表来访问所有属性(实际上是列)的唯一方法。当然,这假设您使用的是默认的按层次结构表继承。它不适用于每个子类的表继承。

考虑到每个层次结构的表的假设意味着您已经在Pet 的所有子类中接受可为空的属性。这是一个要求。所以,你能做的就是

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

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

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

【讨论】:

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