简体   繁体   English

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

[英]Grails: Search with inheritance in domain class

I have this two domain models in my Grails application 我的Grails应用程序中有两个域模型

class Pet {
    String prop1
    String prop2
}

and this 和这个

class Cat extends Pet {
    String prop3
    String prop4
}

Now, in my app, I have many classes that is extending Pets and I want to search Pet with criteria, specifying some properties that cannot exists in other pets. 现在,在我的应用程序中,我有很多类正在扩展Pets ,我想用条件搜索Pet ,指定一些其他宠物不存在的属性。

How can I make possible this operation? 我怎样才能使这个操作成为可能? If I try to make a search, when a result not contains the property, raise an exception. 如果我尝试进行搜索,当结果不包含该属性时,引发异常。

I think, the thing you are trying is not possible. 我想,你正在努力的事情是不可能的。 But you can achieve it using two queries: 但您可以使用两个查询来实现它:

First do a lower level query: 首先做一个较低级别的查询:

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

Since the parent class Pet will have all the fields so doing the above lower level query with any field will work. 由于父类Pet将具有所有字段,因此使用任何字段执行上述较低级别查询将起作用。

Now, get the domain instances using ids: 现在,使用ids获取域实例:

def pets = Pet.getAll(queryResult)

What you're trying to do is impossible due to how object-oriented programming works. 由于面向对象编程的工作原理,您尝试做的事情是不可能的。

class Foo { }
class Bar extends Foo { }

In this example, an instance of Bar is a Foo also. 在这个例子中, Bar的实例也是 Foo But, an instance of Foo is not a Bar . 但是, Foo一个例子不是一个 Bar In other words, a super-class does not know anything about its subclasses, where as a subclass knows about its super-class. 换句话说,一个超类不知道它的子类,其中一个子类知道其超一流的东西。

Back to your example, you cannot access prop3 nor prop4 from Pet simply because they are not Pet properties. 回到你的榜样,你不能访问prop3也不prop4Pet仅仅是因为他们没有Pet的属性。

Working toward a solution 努力寻求解决方案

Given your classes as they are, I agree with Shashank Agrawal's solution. 考虑到你的课程,我同意Shashank Agrawal的解决方案。 An SQL (not HQL or any other GORM query) is the only way to access all of the properties (actually the columns) by querying the pet table. SQL(不是HQL或任何其他GORM查询)是通过查询pet表来访问所有属性(实际上是列)的唯一方法。 Of course, this assumes you're using the default table-per-hierarchy inheritance. 当然,这假设您正在使用默认的每层次表继承。 It will not work with table-per-subclass inheritance. 它不适用于每子类的表继承。

Given the assumption of table-per-hierarchy means you're already accepting nullable properties in all of Pet 's subclasses. 假设每个层次表的假设意味着你已经在所有Pet的子类中接受了可空属性。 It's a requirement. 这是一个要求。 So, what you can do is 所以,你能做的是

  1. Abandon the subclasses 放弃子类
  2. Put all of the properties in Pet 将所有属性放在Pet
  3. Add a property to Pet to specify the pet type. Pet添加属性以指定宠物类型。

Note that this is basically what table-per-hierarchy already does at the database level. 请注意,这基本上是每个层次表在数据库级别已经执行的操作。 The difference is that it would not be inheritance, which makes all of the properties available from Pet . 不同之处在于它不会是继承,这使得Pet可以使用所有属性。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM