4

Рассмотрим следующие классы в весеннем Data JPA (+ Hibernate) Применение:избежать внешних соединений по таблицам при использовании соединенных удела с Spring Data JPA

@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> { } 

Мой самый частый случай использования включает в себя вызов следующий метод (унаследованный от JpaRepository):

IPersonRepository.findAll(); 

Всякий раз, когда этот метод вызывается, следующий запрос SQL выдается Hibernate:

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; 

Всякий раз, когда этот запрос выполняется, меня интересуют только общие поля в классе Person, поэтому я считаю, что левые внешние соединения бесполезны.

Проблема в том, что в нашем реальном приложении есть 8 дочерних классов, таких как Employee и Customer, и миллионы записей в каждой дочерней таблице, которые заставляют запрос на родительскую таблицу работать очень медленно.

Есть ли способ избежать внешних соединений через таблицы в этом случае? Обратите внимание, что я пробовал использовать метод DiscriminatorColumn, и все соединения выполняются в этом случае (при использовании Hibernate). Я также попробовал аннотацию Hibernate-Polymorphism на классы сущности во всех возможных комбинациях, и все же выполняются внешние соединения.

Spring Data JPA version: 1.2.0 
Hibernate version: 4.2.1 

ответ

2

После многих дней, пытаясь решить эту проблему, я пришел к следующему выводу:

  1. Там нет способа, чтобы заставить Hibernate 4.x (и 3.x) не выполнять внешние соединения в этом случае.
  2. Невозможно принудительно использовать последние версии TopLink Essentials (v2.1-60) и OpenJPA (v2.2.2), чтобы не выполнять внешние соединения.
  3. Можно избежать внешних соединений с последней доступной версией EclipseLink (v2.5.0). Однако EclipseLink требует столбец дискриминатора для иерархии классов, показанный выше, хотя Hibernate и OpenJPA этого не делают. До сих пор мне не удалось найти способ избежать использования столбца дискриминатора с EclipseLink.

Я думаю, мне придется ждать изменения спецификации JPA или реализации JPA, чтобы стать доступной, которая удовлетворяет моим текущим требованиям.

 Смежные вопросы

  • Нет связанных вопросов^_^