Search code examples
grailsgrails-ormhibernate-criteria

Grails: Search with inheritance in domain class


I have this two domain models in my Grails application

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.

How can I make possible this operation? If I try to make a search, when a result not contains the property, raise an exception.


Solution

  • 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. But, an instance of Foo is not a 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.

    Working toward a solution

    Given your classes as they are, I agree with Shashank Agrawal's solution. 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. 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. It's a requirement. So, what you can do is

    1. Abandon the subclasses
    2. Put all of the properties in Pet
    3. Add a property to Pet to specify the pet type.

    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.

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