Skip to content

Java Polymorphism Support: filter in abstract Entity.class and subClasses fields #434

@chlegou

Description

@chlegou

Hi there, I have an issue using spring-filter with java polymorphism.
With Spring-boot and Mongo

I'm using the code like this and It's working like a sharm.

// controller
@GetMapping("")
public Page<Entity> filter(@Filter(entityClass = Entity.class) Document document, Pageable pageable) {
    return repository.filter(document, pageable);
}
// repository
@Query("?0")
Page<Entity> filter(Document document, Pageable pageable);

Except when started working with polymorphism and abstract classes.

let's consider these examples:

public class SimpleEntity {} ===> @filter(entityClass = SimpleEntity.class) ====> ✅ WORKING
public class Entity extends AbstractEntity{} ===> @filter(entityClass = Entity.class) ====> ✅ WORKING

Now let's start working with polymorphism and abstract classes:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "type",
        visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = Animal.Cat.class, name = "CAT"),
        @JsonSubTypes.Type(value = Animal.Dog.class, name = "DOG"),
        @JsonSubTypes.Type(value = Animal.Monkey.class, name = "MONKEY"),
})
@Document
public abstract class Animal extends AbstractEntity{  
    //@Filter(entityClass = Animal.class)  ====> supports only Animal.class fileds, not subclasses fields
    private String  name;
    private String  color;
    private long  age;
    private String type;

    //@Filter(entityClass = Animal.class)  ====> :x:  NOT WORKING when searching for field "catAttr1"
    public class Cat extends Animal{
        private String  catAttr1;
        private String  catAttr2;
    }  
    public class Dog extends Animal{
        private String  dogAttr;
    }
    public class Monkey extends Animal{
        private String  monkeyAttr;
    }

}

Having this controller with @filter for the abstract class "Animal.class", let's explore these example to illustrate the issue:

// controller
@GetMapping("")
public Page<Animal> filter(@Filter(entityClass = Animal.class) Document document, Pageable pageable) {
    return repository.filter(document, pageable);
}

URl/?filter=name~'testName' and age >:'5' ====> ✅ WORKING

URl/?filter=name~'testName' and catAttr1~'cute cat Value' ====> ❌ NOT WORKING when searching for field "catAttr1"

we get an exception when searching for subclasses fields. since it"s unknown.
and we can't have multiple endpoints, one for each subClass, since we have many subclasses and this will not be a clean code.

proposing a solution:

Using this lib:

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.10.2</version>
</dependency>

and with this method

public static <T> List<Class<? extends T>> findSubclasses(Class<T> parentClass) {
    Reflections reflections = new Reflections("com.mypackage");
    return reflections.getSubTypesOf(parentClass).stream().toList();
}

we could get the Animal.class subclasses. so we could extend @filter(entityClass = Animal.class) fields louckup to entityClass fields and subclasses fields.

could you please enhance the lib to support polymorphism feature?

Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions