Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redundant JOIN Generated with @EntityGraph in Spring Data JPA Query Methods #3717

Closed
amiriahmad72 opened this issue Dec 16, 2024 · 3 comments

Comments

@amiriahmad72
Copy link

amiriahmad72 commented Dec 16, 2024

Issue: Redundant JOIN Generated with @EntityGraph in Spring Data JPA Query Methods

When using @EntityGraph in a repository method that relies on query generation by method name (without explicitly defining a query using @Query or @NamedQuery), redundant JOIN statements are generated if the method name references a relationship that is also included in the attributePaths of @EntityGraph.

Environment:

  • Java 21
  • Spring Boot 3.4.0 (Spring Data 3.4.0)

Steps to Reproduce:

You can reproduce this issue using this sample project. The project includes two test cases, one of which fails due to the issue.

I captured the generated SQL statements using a Hibernate interceptor and verified the occurrence count of JOIN operations.

Entities:

Here are the entity definitions:

@Setter
@Getter
@Entity
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Nationalized
    @Column(length = 255, unique = true, nullable = false)
    private String name;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Company company;

}
@Setter
@Getter
@Entity
public class Company {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Nationalized
    @Column(length = 255, unique = true, nullable = false)
    private String name;

    private boolean enable;

}

Repository Methods:

The EmployeeRepository contains the following two methods:

public interface EmployeeRepository extends JpaRepository<Employee, Long> {

    @EntityGraph(attributePaths = "company")
    Set<Employee> findAllByCompanyEnableIsTrue();

    @EntityGraph(attributePaths = "company")
    @Query("""
            SELECT e
            FROM Employee e
            WHERE e.company.enable
            """)
    Set<Employee> findAllByCompanyEnableIsTrueUsingQuery();

}

Generated SQL Queries:

For the first method (findAllByCompanyEnableIsTrue), which relies on the method name for query generation, the following SQL is generated:

select
    e1_0.id,
    e1_0.company_id,
    c2_0.id,
    c2_0.enable,
    c2_0.name,
    e1_0.name
from employee e1_0
join company c1_0 on c1_0.id = e1_0.company_id
join company c2_0 on c2_0.id = e1_0.company_id
where c1_0.enable

As shown, there is a redundant JOIN.

However, for the second method (findAllByCompanyEnableIsTrueUsingQuery), which uses an explicitly defined query, the generated SQL is:

select
    e1_0.id,
    e1_0.company_id,
    c1_0.id,
    c1_0.enable,
    c1_0.name,
    e1_0.name
from employee e1_0
join company c1_0 on c1_0.id = e1_0.company_id
where c1_0.enable

This query avoids the redundant JOIN.

Expected Behavior:

The query generated for the method using the method name (findAllByCompanyEnableIsTrue) should avoid redundant JOIN statements, similar to the query generated by findAllByCompanyEnableIsTrueUsingQuery.

Observed Behavior:

Using @EntityGraph with query methods generated by method name causes redundant JOIN operations when a relationship is referenced in both the method name and the attributePaths of @EntityGraph.

Additional Information:

Please let me know if further clarification or additional examples are needed.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 16, 2024
@amiriahmad72 amiriahmad72 changed the title using entitygraph with jpa query method-name may generate redundant join Redundant JOIN Generated with @EntityGraph in Spring Data JPA Query Methods Dec 16, 2024
@christophstrobl
Copy link
Member

Thank you for getting in touch. Spring Data is not in control of the final SQL generated by the persistence provider. The derived query is using the criteria API, the annotated one is based on JPQL. Please try to reproduce the issue using the EntityManager alone without any of the spring bits around. If your observation is the same, please report it to the hibernate team.

@christophstrobl christophstrobl added the status: waiting-for-feedback We need additional information before we can continue label Dec 17, 2024
@spring-projects-issues
Copy link

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@spring-projects-issues spring-projects-issues added the status: feedback-reminder We've sent a reminder that we need additional information before we can continue label Dec 24, 2024
@spring-projects-issues
Copy link

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

@spring-projects-issues spring-projects-issues closed this as not planned Won't fix, can't repro, duplicate, stale Dec 31, 2024
@spring-projects-issues spring-projects-issues removed status: waiting-for-feedback We need additional information before we can continue status: feedback-reminder We've sent a reminder that we need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged labels Dec 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants