Avoid external joins between tables when using federated inheritance using Spring Data JPA

Consider the following classes in the application.

@Entity @Inheritance(strategy = InheritanceType.JOINED) @Table(name = "person") public class Person { } @Entity @Table(name = "customer") public class Customer extends Person { } @Entity @Table(name = "employee") public class Employee extends Person { } @Entity @Table(name = "manager") public class Manager extends Employee { } public interface IPersonRepository extends JpaRepository<Person, Long> { } public interface ICustomerRepository extends JpaRepository<Customer, Long> { } public interface IEmployeeRepository extends JpaRepository<Employee, Long> { } 

My most common use case involves calling the following method (inherited from JpaRepository ):

 IPersonRepository.findAll(); 

When calling this method, Hibernate issues the following SQL query:

 select person0_.id as id1_3_, person0_.version as version2_3_, person0_.first_name as first3_3_, person0_.last_name as last4_3_, person0_1_.customer_code as customer1_0_, person0_2_.employee_code as employee1_1_, person0_2_.manager_id as manager3_1_, case when person0_3_.id is not null then 3 when person0_1_.id is not null then 1 when person0_2_.id is not null then 2 when person0_.id is not null then 0 end as clazz_ from person person0_ left outer join customer person0_1_ on person0_.id=person0_1_.id left outer join employee person0_2_ on person0_.id=person0_2_.id left outer join manager person0_3_ on person0_.id=person0_3_.id; 

Whenever this query is executed, I am only interested in the common fields in the Person class, so I believe that left outer joins are useless.

The problem is that in our real application there are 8 child classes, such as Employee and Customer , and millions of records in each child table, which make the query on the parent table work very slowly.

Is there a way to avoid outer joins in tables in this case? Please note that I tried using the DiscriminatorColumn approach, in which case all connections are made (when using Hibernate). I also tried the Hibernate Polymorphism annotation for entity classes in all possible combinations, and yet external joins are performed.

 Spring Data JPA version: 1.2.0 Hibernate version: 4.2.1 
+4
source share
1 answer

After many days of trying to solve this problem, I came to the following conclusion:

  • It is not possible to force Hibernate 4.x (and 3.x) not to perform external connections in this case.
  • It is not possible to force the latest available versions of TopLink Essentials (v2.1-60) and OpenJPA (v2.2.2) to not make external connections.
  • You can avoid external connections with the latest available version of EclipseLink (v2.5.0). However, EclipseLink does require the discriminator column for the class hierarchy shown above, although Hibernate and OpenJPA do not. So far, I have not been able to find a way to avoid using the discriminator column using EclipseLink.

I think I will have to wait until the JPA specification changes or the JPA implementation becomes available that will satisfy my current requirements.

+2
source

Source: https://habr.com/ru/post/1480687/


All Articles