Skip to content

Eagerly fetched to-one reference is INNER-joined when the attribute is used in a filter condition #5393

Description

@KremnevDmitry

Environment

Jmix version: 2.8.999-SNAPSHOT

Bug Description

When a to-one reference is both eagerly fetched (present in the loader's fetch plan, e.g. to show it as a data grid column) and used in a filter condition, it is joined with an INNER join. Entities whose reference value is null are then dropped from the whole result —including when the condition is an OR and the entity matches the other branch.

Minimal reproduction project: inner-join-bug.zip

Steps to reproduce

Entities:

  • Project (id, name)
  • Task (id, name, project)project is @ManyToOne(fetch = LAZY), optional.

Data — two tasks whose names both contain Task; one has a project, the other has project = null.

Load Task with project in the fetch plan and an OR condition that references project:

dataManager.load(Task.class)
        .condition(LogicalCondition.or(
                PropertyCondition.equal("project", jmixProject),
                PropertyCondition.contains("name", "Task")))
        .fetchPlan(fp -> fp.addFetchPlan(FetchPlan.BASE).add("project", FetchPlan.BASE))
        .list();

In the UI: a Task list view with a Project column (so project is fetched) and a GenericFilter group project = Jmix OR name contains 'Task'.

Actual behavior

Only the task that has a project is returned; the task with project = null is dropped, although it matches the name contains 'Task' branch.

Generated SQL — comma-style INNER join whose correlation is placed at the top level of
WHERE (outside the OR):

SELECT t1.*, t0.* FROM PROJECT t0, TASK t1
WHERE (((t1.PROJECT_ID = ?) OR LOWER(t1.NAME) LIKE ?) AND (t0.ID = t1.PROJECT_ID))

The row is lost only when the reference is both fetched and used in the condition:

-- fetched, NOT used in the condition -> LEFT OUTER JOIN (correct, keeps null-reference rows)
SELECT t1.*, t0.* FROM TASK t1 LEFT OUTER JOIN PROJECT t0 ON (t0.ID = t1.PROJECT_ID)
WHERE LOWER(t1.NAME) LIKE ?

-- used in the condition, NOT fetched -> FK comparison, no join (correct)
SELECT * FROM TASK WHERE ((PROJECT_ID = ?) OR LOWER(NAME) LIKE ?)

Expected behavior

The task with project = null must be returned (it matches the OR branch). The fetched reference should be joined with a LEFT (outer) join —as it already is when the reference is not used in the condition — so that filtering does not drop rows.

Metadata

Metadata

Assignees

Type

No fields configured for Bug.

Projects

Status
Next

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions