Skip to content

Specifications with sort creates additional join even though the entity was already fetched #2253

Open
@michalkrajcovic

Description

@michalkrajcovic

Hi, specifications with sort creates additional join even though the entity was already fetched. The result is that the table is then left joined twice. Consider setup:
entities

@Entity
public class A {
    @Id
    Long id

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "b_id")
    B b;
}

@Entity
public class B {
    @Id
    Long id
    String name
}

specifications

Specification<A> specification =
(root, query, builder) -> {
   query.distinct(true); 
   root.fetch(A_.b, JoinType.LEFT);
   return builder.equal(root.get(A_.id), 1L);
};

Sort sort = Sort.by(Sort.Direction.ASC, "b.name");

aRepository.findAll(specification, sort);

then
List<T> findAll(Specification<T> spec, Sort sort);

creates SQL query

select distinct A1.id, A1.b_id, B2.id, B2.name
from A A1
    left join B B1 on A1.b_id = B1.id
    left join B B2 on A1.b_id = B2.id
where A.id = 1
order by B1.name asc

B entity is joined twice. If the query is distinct, then it fails with SQL error
Expression #1 of ORDER BY clause is not in SELECT list, references column ... B1.name ... which is not in SELECT list; this is incompatible with DISTINCT
The SQL error in this case is correct, order by clause is not in select list. The sort should not create additional join if the entity was already fetched or joined.

The commit that introduced this behaviour is 43d1438

Previously, it checked whether there already is a fetched entity (isAlreadyFetched() method) if yes then it didn’t create additional join (getOrCreateJoin() method). The logic was changed to check whether the entity was already inner-joined. But even if I change the join type in specification to JoinType.INNER (root.fetch(A_.b, JoinType.INNER);) it still creates additional join.

Possible duplicate of #2206

Metadata

Metadata

Labels

status: blockedAn issue that's blocked on an external project change

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions