Hibernate – avoids cross-table external connections when connecting inherited using the Spring Data JPA connection

Consider the following classes in a Spring Data JPA (Hibernate) 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 { }
public interface ICustomerRepository extends JpaRepository {}
public interface IEmployeeRepository extends JpaRepository {}

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

IPersonRepository.findAll();

Whenever this method is called, Hibernate will issue the following SQL query:

select
person0_.id as id1_3_,
person0_.version as version2_3_,
pers on0_.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 manager />3_1_,
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 public fields in the Person class, so I find that the left outer join is useless.

The problem is that in our actual application, there are 8 sub-categories, such as Employee and Customer, and millions of records in each sub-table, these records cause the query on the parent table to run very slowly.

In this case, is there a way Avoid outer joins in the table? Please note that I have tried the DiscriminatorColumn method and still perform the join in this case (when using Hibernate). I also tried the Hibernate-specific Polymorphism annotation on the entity class in all possible combinations, and the outer join is still performed .

Spring Data JPA version: 1.2.0
Hibernate version: 4.2.1

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

>In this case, there is no way to force Hibernate 4. x (and 3.x) do not perform outer joins.
>Cannot force the use of the latest version of TopLink Essentials (v2.1-60) and OpenJPA (v2.2.2) to perform outer joins.
>You can use the latest version Version of EclipseLink (v2.5.0) to avoid outer joins. However, EclipseLink requires the discriminator column of the class hierarchy shown above, even if Hibernate and OpenJPA do not. So far, I have not been able to find a way to avoid using the discriminator column in EclipseLink Method.

I think I will have to wait to change the JPA specification or I can use a JPA implementation that meets my current requirements.

Consider Spring Data JPA( The following classes in the Hibernate) 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 {}

@E ntity
@Table(name = "manager")
public class Manager extends Employee {}

public interface IPersonRepository extends JpaRepository {}
public interface ICustomerRepository extends JpaRepository {}
public interface IEmployeeRepository extends JpaRepository {}

My most common use case involves calling the following methods (inherited from JpaRepository):< /p>

IPersonRepository.findAll();

Whenever this method is called, Hibernate will issue 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 no t 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 public fields in the Person class, so I find that the left outer join is useless.

The problem is that in our actual application, There are 8 sub-categories, such as Employee and Customer, and millions of records in each sub-table, these records cause the query on the parent table to run very slowly.

In this case, is there any Ways to avoid outer joins in the table? Please note that I have tried the DiscriminatorColumn method and still perform the join in this case (when using Hibernate). I also tried the Hibernate-specific Polymorphism annotation on the entity class in all possible combinations, and the outer join is still performed .

Spring Data JPA version: 1.2.0
Hibernate version: 4.2.1

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

>In this case, there is no way to force Hibernate 4.x (and 3.x) not to perform outer joins.
>Cannot force the use of the latest version of TopLink Essentials (v2.1-60) and OpenJPA (v2.2.2) to perform outer joins.
>You can use the latest version of EclipseLink (v2.5.0) to avoid outer joins However, EclipseLink requires the discriminator column of the class hierarchy shown above, even if Hibernate and OpenJPA do not. So far, I have not been able to find a way to avoid using the discriminator column in EclipseLink.

I think I Will have to wait to change the JPA specification or can use a JPA implementation that meets my current requirements.

Leave a Comment

Your email address will not be published.