2015-11-18 3 views
6

Рассмотрим следующую модельJPA: Как извлечь жадностью вложенной коллекции элементов

@Entity 
// JPA and JAXB annotations here 
public class Employee implements Serializable { 
    // other fields, annotations, stuffs 
    ... 
    @ElementCollection(fetch = FetchType.LAZY, 
     targetClass = Address.class) 
    @CollectionTable(name = "employee_address", 
     schema = "hris", 
     joinColumns = @JoinColumn(name = "employee_id", 
       nullable = false, 
       referencedColumnName = "employee_id", 
       foreignKey = @ForeignKey(ConstraintMode.CONSTRAINT))) 
    protected Set<Address> addresses; 
    // setters, getters 
    ... 
} 

@Embeddable 
// JAXB annotations here 
public class Address implements Serializable { 
     // fields, setters, getters 
} 

Address класс помечается @Embeddable аннотацию, а Employee класс имеет встроенный элемент коллекции из addresses. Элемент коллекции fetch установлен в FetchType.LAZY. Теперь я хотел бы создать @NamedQuery, который будет извлекать всех сотрудников с адресами, которые с нетерпением инициализируются. Зная, что JOIN FETCHwill only work with entity collections аннотируется с @OneToMany или @ManyToMany на основе JPA 2.1, как бы создать действительный запрос JPQL, который позволит мне с нетерпением получить коллекции встроенных элементов?

+0

Как вы пришли к выводу, что 'join fetch' работает только с объектами? Вы попробовали? –

+0

@DraganBozanovic: на основании документации, «Ассоциация, на которую ссылается правая сторона предложения FETCH JOIN, должна быть ассоциацией, которая принадлежит сущности, которая возвращается в результате запроса. Не разрешается указывать идентификационной переменной для объектов, на которые ссылается правая сторона предложения FETCH JOIN, и, следовательно, ссылки на неявно получаемые объекты не могут появляться в другом месте запроса ». –

+0

Путь к коллекции должен быть разрешен в поле ассоциации –

ответ

2

В спецификации JPA 2.1 (JSR 338) Я не могу найти намека на то, что fetch-соединения работают только на отношения сущностей (но не встраиваемые). JSR 338, раздел 4.4.5.3 даже заявляет:

FETCH JOIN позволяет выборку объединения или элемента коллекции в качестве побочного эффекта выполнения запроса.

В качестве другого намека на следующий минимальный пример (по существу, напоминающее Ваш) выполнен с Hibernate 4.3.11 в качестве результатов JPA поставщика в одном запросе:

Адрес: встраиваемая лица

@Embeddable public class Address { private String city; } 

сотрудников:

@Entity public class Employee { 

    @Id private Long id; 

    @ElementCollection(fetch = FetchType.LAZY) 
    @CollectionTable(name = "address", 
      joinColumns = @JoinColumn(name="employee_id")) 
    private Set<Address> addresses; 

} 

JPQL Запрос:

em.createQuery("select e from Employee e join fetch e.addresses").getResultList(); 

Результирующий SQL-запрос:

select 
    employee0_.id as id1_1_, 
    addresses1_.employee_id as employee1_1_0__, 
    addresses1_.city as city2_5_0__ 
from 
    Employee employee0_ 
inner join 
    address addresses1_ on employee0_.id=addresses1_.employee_id 

Так выше запрос JPQL кажется, чтобы решить вашу проблему.

2

Кстати, более эффективный способ может быть не использовать соединение, но подвыбор

@Fetch(FetchMode.SUBSELECT) 
@BatchSize(size=500) 

это делает два выбирает, вместо одного, но не производит так много двусмысленности.

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