Inherited grails domain classes missing dynamic properties

Chris Erickson

I'm having a problem where the related table id fields return 'null' from my domain objects when using inheritance. Here is an example:

In /src/groovy/

BaseClass1.groovy

class BaseClass1 {
    Long id
    static mapping = {
        tablePerConcreteClass true
    }
}

BaseClass2.groovy

class BaseClass2 extends BaseClass1 {
    String someOtherProperty
    static constraints = {
        someOtherProperty(maxSize:200)
    }
    static mapping = BaseClass1.mapping
}

In /grails-app/domain

ParentClass.groovy

class ParentClass extends BaseClass2 {
    ChildClass myChild

    static mapping = BaseClass2.mapping << {
        version false
    }
}

ChildClass.groovy

class ChildClass extends BaseClass1 {
    String property

    static mapping = BaseClass1.mapping
}

The problem appears here:

SomeotherCode.groovy

print parentClassInstance.myChild.id // returns the value
print parentClassInstance.myChildId // returns null

Any ideas what might be going on to get those dynamic properties to break like this?

Chris Erickson

After debugging into the get(AssociationName)Id source, I found the following: The handler for this is:

GrailsDomainConfigurationUtil.getAssociationIdentifier(Object target, String propertyName,
        GrailsDomainClass referencedDomainClass) {

    String getterName = GrailsClassUtils.getGetterName(propertyName);

    try {
        Method m = target.getClass().getMethod(getterName, EMPTY_CLASS_ARRAY);
        Object value = m.invoke(target);
        if (value != null && referencedDomainClass != null) {
            String identifierGetter = GrailsClassUtils.getGetterName(referencedDomainClass.getIdentifier().getName());
            m = value.getClass().getDeclaredMethod(identifierGetter, EMPTY_CLASS_ARRAY);
            return (Serializable)m.invoke(value);
        }
    }
    catch (NoSuchMethodException e) {
        // ignore
    }
    catch (IllegalAccessException e) {
        // ignore
    }
    catch (InvocationTargetException e) {
        // ignore
    }
    return null;
}

It threw an exception on the related class (value.getClass().getDeclaredMethod), saying NoSuchMethod for the method getId(). I was unable to remove the id declaration from the base class without Grails complaining that an identifier column was required. I tried marking id as public and it also complained that it wasn't there. So, I tried this

BaseClass {
    Long id
    public Long getId() { return this.@id }
}

and things worked on some classes, but not on others.

When I removed the ID declaration, I go an error: "Identity property not found, but required in domain class". On a whim, I tried adding @Entity to the concrete classes and viola! everything started working.

class BaseClass {
    //Don't declare id!
}

@Entity
class ParentClass {}

@Entity
class ChildClass {}

I still think it is a grails bug that it needs to be added, but at least it is easy enough to work around.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Inherited frames - missing properties

Grails get domain properties

Attributes difference in inherited classes properties

Losing sub classes' properties in a collection of inherited classes

Refactor Grails Domain Classes with inheritance

ExpressJS SubClasses Missing Inherited attributes and properties in Callbacks

Grails: How to write traits for domain classes?

Using Java beans as Grails domain classes

Grails 3.3.2 domain classes inheritance issue

Relationships between Grails domain classes with inheritance

Proper Implementation of clone() For Domain Classes to duplicate a Grails domain instance

How access properties of Inherited classes from abstract class

How can I sort a List by DateTime properties of inherited classes?

Are these inherited properties?

missing of domain and controller under grails-app in GGTS 2.2.1

grails method missing exception when trying to find null value in domain

Is there a reason not to map all integer types to a BigInteger in Grails Domain Classes?

How do I map Grails Domain Classes to DTOs?

Grails 3.0 / IntelliJ 14.1.4 creating controllers, services, domain classes not working

Include transient domain class properties as restful json or xml response in grails

Grails Domain Design: inheritance or one class with nullable properties?

Missing } in less generating dynamic classes using loop

How to show missing CSS classes and properties in Google Chrome?

Distinguish null from missing properties in Jackson using Kotlin data classes

How do classes inherited from namedtuple maintain access to parent properties with a redefined __init__?

Spring Autowiring in Inherited Classes

Overloading methods in inherited classes

Inherited Abstract Classes in python

Dictionary - inherited classes