Skip to content

QuerydslPredicateOperationCustomizer exclude static fields and support QuerydslBindings#excludeUnlistedProperties feature #866

Closed
@noahlann

Description

@noahlann

Situation 1:

i have a entity like this:

// ignore package & import

@Data
@Entity
@Table(schema = "application", name = "application")
@Schema(description = "app")
@EntityListeners(AuditingEntityListener.class)
@NamedEntityGraph(name = "Application.Graph", attributeNodes = {@NamedAttributeNode("oauth2")})
public class Application implements Serializable {
    private static final long serialVersionUID = 6582562282311194139L;

    @Id
    @Column(length = 64)
    @GeneratedValue(generator = "snowflakeId")
    @GenericGenerator(name = "snowflakeId", strategy = "org.lan.iti.common.data.orm.jpa.generator.SnowflakeId")
    @Schema(description = "id")
    private String id;

    @Column(nullable = false, length = 64)
    @Schema(description = "name")
    private String name;

    @Column(length = 1024)
    @Schema(description = "description")
    private String description;

    @Column(length = 32)
    @Schema(description = "app type")
    @Enumerated(EnumType.STRING)
    private AppType type = AppType.EXTERNAL;

    @Column
    @Schema(description = "icon")
    private String icon;

    @Column(nullable = false)
    @CreatedDate
    @Schema(description = "createTime")
    private LocalDateTime createTime;

    @Column(length = 1024)
    @Schema(description = "rsa-publicKey")
    private String publicKey;

    @Column(length = 16, nullable = false)
    @Enumerated(EnumType.STRING)
    @Schema(description = "status")
    private AuditStatus auditStatus = AuditStatus.UN_SUBMITTED;

    @Column
    @Schema(description = "auditTime")
    private LocalDateTime auditTime;

    // region associate...
    @OneToOne(mappedBy = "application", fetch = FetchType.LAZY,
            cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
    @JsonManagedReference("app_oauth2")
    private OAuthClientDetails oauth2;
    // endregion

    public enum AuditStatus {
        UN_SUBMITTED,
        PENDING,
        APPROVED,
        FAILED
    }

    public enum AppType {
        INNER,
        EXTERNAL
    }
}

normally, QuerydslPredicateOperationCustomizer add all the entity fields, include static fields...

i get this
image

we don't need static fields of the entity in usually.

so we need exclude these static fields.

// org.springdoc.data.rest.customisers.QuerydslPredicateOperationCustomizer#customize

Set<String> fieldsToAdd = Arrays.stream(predicate.root().getDeclaredFields())
                        .filter(field -> !Modifier.isStatic(field.getModifiers()))
                        .map(Field::getName).collect(Collectors.toSet());

Situation 2:

Support QuerydslBindings.excludeUnlistedProperties feature.

i have customize QuerydslBindings with bindings.excludeUnlistedProperties(true);

    @Override
    default void customize(@NonNull QuerydslBindings bindings, @NonNull QApplication root) {
        bindings.excludeUnlistedProperties(true);
        // bind...
        bindings.bind(root.name).first(StringExpression::containsIgnoreCase);
//        bindings.excluding(root.icon, root.publicKey, root.description);
    }

i just want the field that root.name for query parameter.

maybe this way:

org.springdoc.data.rest.customisers.QuerydslPredicateOperationCustomizer#customize

boolean excludeUnlistedProperties = getFieldValueOfBoolean(bindings, "excludeUnlistedProperties", null);
            for (String fieldName : fieldsToAdd) {
                Type type = getFieldType(fieldName, pathSpecMap, predicate.root(), excludeUnlistedProperties);
                if (type != null) {
                    Parameter newParameter = buildParam(type, fieldName);

                    parametersToAddToOperation.add(newParameter);
                }
            }
private Type getFieldType(String fieldName, Map<String, Object> pathSpecMap, Class<?> root, boolean excludeUnlistedProperties) {
        try {
            Object pathAndBinding = pathSpecMap.get(fieldName);
            Optional<Path<?>> path = getPathFromPathSpec(pathAndBinding);

            Type genericType;
            Field declaredField = null;
            if (path.isPresent()) {
                genericType = path.get().getType();
            } else if (!excludeUnlistedProperties) {
                declaredField = root.getDeclaredField(fieldName);
                genericType = declaredField.getGenericType();
            } else {
                return null;
            }
            if (genericType != null) {
                return genericType;
            }
        } catch (NoSuchFieldException e) {
            LOGGER.warn("Field {} not found on {} : {}", fieldName, root.getName(), e.getMessage());
        }
        return String.class;
    }

i got what i want:

image

sorry for my poor english.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions