From f7100e2bbaa629d28cb881300c04dd25e35a24ac Mon Sep 17 00:00:00 2001 From: THOREL Arnaud Date: Mon, 16 Mar 2026 15:03:08 +0100 Subject: [PATCH] fix: correct inheritance fields issue Scan all fields from the class hierarchy (class + superclasses) instead of only declared fields of the direct class. Co-Authored-By: Claude Sonnet 4.6 --- .../scanner/FilterFieldAnnotationScanner.java | 74 ++++++++++++------- .../dummy/DummyRequestWithInheritance.java | 14 ++++ .../FilterFieldAnnotationScannerTest.java | 14 +++- 3 files changed, 71 insertions(+), 31 deletions(-) create mode 100644 src/test/java/fr/ouestfrance/querydsl/dummy/DummyRequestWithInheritance.java diff --git a/src/main/java/fr/ouestfrance/querydsl/service/scanner/FilterFieldAnnotationScanner.java b/src/main/java/fr/ouestfrance/querydsl/service/scanner/FilterFieldAnnotationScanner.java index 1160dd4..95b757b 100644 --- a/src/main/java/fr/ouestfrance/querydsl/service/scanner/FilterFieldAnnotationScanner.java +++ b/src/main/java/fr/ouestfrance/querydsl/service/scanner/FilterFieldAnnotationScanner.java @@ -43,36 +43,36 @@ public List scan(Class clazz) { List violations = new ArrayList<>(); - Arrays.stream(clazz.getDeclaredFields()) + getAllFields(clazz).stream() .filter(this::hasFilterFieldAnnotation) .forEach( - field -> { - FilterFields filterFields = field.getAnnotation(FilterFields.class); - List groupFilters = new ArrayList<>(); - if (filterFields!= null && !filterFields.groupName().isEmpty()) { - groupFilters.addAll(Arrays.stream(filterFields.value()).toList()); - GroupFilter filterAndGroup = new GroupFilter(UUID.randomUUID().toString(), new ArrayList<>(), GroupFilter.Operand.AND); - Arrays.stream(filterFields.value()) - .forEach(filterField -> { - SimpleFilter filter = new SimpleFilter(firstNotEmpty(filterField.key(), field.getName()), filterField.operation(), filterField.orNull(), field); - validatorService.validate(filter).ifPresent(violations::add); - filterAndGroup.filters().add(filter); - }); - appendToGroup(rootGroup, filterFields.groupName(), filterAndGroup); - } - - // On filterField - Arrays.stream(field.getAnnotationsByType(FilterField.class)) - .filter(x-> !groupFilters.contains(x)) - .forEach( - filterField -> { - SimpleFilter filter = new SimpleFilter(firstNotEmpty(filterField.key(), field.getName()), filterField.operation(), filterField.orNull(), field); - validatorService.validate(filter).ifPresent(violations::add); - appendToGroup(rootGroup, filterField.groupName(), filter); + field -> { + FilterFields filterFields = field.getAnnotation(FilterFields.class); + List groupFilters = new ArrayList<>(); + if (filterFields != null && !filterFields.groupName().isEmpty()) { + groupFilters.addAll(Arrays.stream(filterFields.value()).toList()); + GroupFilter filterAndGroup = new GroupFilter(UUID.randomUUID().toString(), new ArrayList<>(), GroupFilter.Operand.AND); + Arrays.stream(filterFields.value()) + .forEach(filterField -> { + SimpleFilter filter = new SimpleFilter(firstNotEmpty(filterField.key(), field.getName()), filterField.operation(), filterField.orNull(), field); + validatorService.validate(filter).ifPresent(violations::add); + filterAndGroup.filters().add(filter); + }); + appendToGroup(rootGroup, filterFields.groupName(), filterAndGroup); } - ); - } - ); + + // On filterField + Arrays.stream(field.getAnnotationsByType(FilterField.class)) + .filter(x -> !groupFilters.contains(x)) + .forEach( + filterField -> { + SimpleFilter filter = new SimpleFilter(firstNotEmpty(filterField.key(), field.getName()), filterField.operation(), filterField.orNull(), field); + validatorService.validate(filter).ifPresent(violations::add); + appendToGroup(rootGroup, filterField.groupName(), filter); + } + ); + } + ); // Check for violations if (!violations.isEmpty()) { @@ -83,9 +83,10 @@ public List scan(Class clazz) { /** * Append a filter to a groupName, if no group found, it will compute a new OR Group + * * @param rootGroup root group * @param groupName name of the searched group - * @param filter filter to append + * @param filter filter to append */ private void appendToGroup(GroupFilter rootGroup, String groupName, Filter filter) { if (groupName.isEmpty()) { @@ -103,6 +104,7 @@ private void appendToGroup(GroupFilter rootGroup, String groupName, Filter filte /** * Retrieve a rootGroup by its name + * * @param rootGroup rootGroup * @param groupName name of the searched rootGroup * @return optional rootGroup @@ -115,6 +117,22 @@ private Optional getGroup(GroupFilter rootGroup, String groupName) .findFirst(); } + /** + * Collect all fields from the class hierarchy (class + all superclasses up to Object) + * + * @param clazz class to inspect + * @return list of all declared fields + */ + private List getAllFields(Class clazz) { + List fields = new ArrayList<>(); + Class current = clazz; + while (current != null && current != Object.class) { + fields.addAll(Arrays.asList(current.getDeclaredFields())); + current = current.getSuperclass(); + } + return fields; + } + /** * Return the fieldName by getting the first item not empty * diff --git a/src/test/java/fr/ouestfrance/querydsl/dummy/DummyRequestWithInheritance.java b/src/test/java/fr/ouestfrance/querydsl/dummy/DummyRequestWithInheritance.java new file mode 100644 index 0000000..8e363ed --- /dev/null +++ b/src/test/java/fr/ouestfrance/querydsl/dummy/DummyRequestWithInheritance.java @@ -0,0 +1,14 @@ +package fr.ouestfrance.querydsl.dummy; + +import fr.ouestfrance.querydsl.FilterField; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class DummyRequestWithInheritance extends DummyRequest { + + @FilterField(key = "anotherProductCode") + private String anotherCode; +} + diff --git a/src/test/java/fr/ouestfrance/querydsl/service/scanner/FilterFieldAnnotationScannerTest.java b/src/test/java/fr/ouestfrance/querydsl/service/scanner/FilterFieldAnnotationScannerTest.java index d085dd4..b5a6c8c 100644 --- a/src/test/java/fr/ouestfrance/querydsl/service/scanner/FilterFieldAnnotationScannerTest.java +++ b/src/test/java/fr/ouestfrance/querydsl/service/scanner/FilterFieldAnnotationScannerTest.java @@ -2,9 +2,9 @@ import fr.ouestfrance.querydsl.dummy.DummyRequest; import fr.ouestfrance.querydsl.dummy.DummyRequestOrGroupMultipleField; +import fr.ouestfrance.querydsl.dummy.DummyRequestWithInheritance; import fr.ouestfrance.querydsl.model.Filter; import fr.ouestfrance.querydsl.model.GroupFilter; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.util.List; @@ -15,18 +15,26 @@ class FilterFieldAnnotationScannerTest { private final FilterFieldAnnotationScanner scanner = new FilterFieldAnnotationScanner(); + @Test - void shouldScanModel(){ + void shouldScanModel() { List scan = scanner.scan(DummyRequest.class); assertNotNull(scan); assertEquals(6, scan.size()); } @Test - void shouldScanGroupMultiFieldModel(){ + void shouldScanGroupMultiFieldModel() { List scan = scanner.scan(DummyRequestOrGroupMultipleField.class); assertNotNull(scan); assertEquals(1, scan.size()); assertEquals(1, scan.stream().filter(GroupFilter.class::isInstance).count()); } + + @Test + void shouldScanInheritanceFieldsModel() { + List scan = scanner.scan(DummyRequestWithInheritance.class); + assertNotNull(scan); + assertEquals(7, scan.size()); + } }