Skip to content

GenericFilter: restoring filter state from the URL fires a redundant data load when a condition operation differs #5655

Description

@fractal3000

Environment

Jmix version: 3.0.1

Bug Description

Performance problem. When the filter state is restored from URL query parameters and the operation of a condition in the URL differs from the one stored in the current configuration, the view fires a redundant intermediate data load before the final one — two loads per navigation instead of one.

Mechanics: GenericFilterUrlQueryParametersBinder.updatePropertyCondition applies the operation from the URL to the live condition component (configurationComponent.setOperation(...)). The operation-change listener registered by GroupFilter.add does not distinguish this programmatic call from a user gesture and unconditionally invokes GroupFilter.apply(); for the delegated root group its apply() skips recomposition but still calls dataLoader.load() (there is no isAttached() check, unlike SingleFilterComponentBase.apply()). The restore then finishes with its own composition and load. Value changes do not add loads (UiComponentUtils.setValue is not a client-side change).

The intermediate load runs the full pipeline — the SELECT, the pagination count query, entity materialization by the fetch plan, row-level security — and its result is immediately discarded. For a view whose query takes ~400 ms, opening a deep link pays roughly double. The condition of the discarded load also differs from the final one, so on large tables it may hit a worse query plan than the final load itself.

The gap is reached with default settings whenever a user changes a condition operation (conditions added by the user and saved configurations have operationEditable = true by default) and the URL is then reopened — F5, browser Back, a bookmark, a link shared with a colleague.

Steps To Reproduce

  1. A list view with a GenericFilter bound to the data loader and an urlQueryParameters facet with the genericFilter binder; a configuration whose condition has an editable operation, e.g.:

    <configurations>
        <configuration id="byStatus" name="By status">
            <propertyFilter property="status" operation="EQUAL" operationEditable="true"/>
        </configuration>
    </configurations>
  2. Count data loads, e.g. with a PostLoadEvent listener on the loader, or enable SQL logging.

  3. Select the configuration, pick a value, change the operation (=<>): the URL now carries ..._genericFilterCondition=property:status_not-equal_....

  4. Open the resulting URL in a fresh tab (or press F5).

Current Behavior

Two data loads. With a load journal on the view:

Loads: 2 — load #1: AND[status not_equal OPEN]  |  load #2: AND[status not_equal OPEN, AND[status not_equal OPEN]]

The same URL with the matching operation (..._equal_...) produces one load — the only difference between the two URLs is the operation token.

Expected Behavior

One data load per navigation: the restore applies the URL state as a single composition and loads once.

Notes

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions