Как получить вложенные объекты JPA в одном запросе - PullRequest
0 голосов
/ 15 июля 2011

Я пытаюсь получить объекты, используя eclipselink JPA, и ищу способ уменьшить количество запросов, выполняемых для получения одного объекта. Я считаю, что я должен использовать аннотацию @JoinFetch для извлечения дочерних объектов в том же запросе, что и основной объект. Это хорошо работает для одного уровня объединения, но не для нескольких уровней.

В приведенном ниже примере EntityA содержит коллекцию EntityB, которая содержит EntityC. Когда я получаю EntityA, я хочу, чтобы один запрос возвратил все 3 набора данных сущности. В действительности он генерирует 2 запроса: 1, соединяющий EntityA и EntityB, а затем отдельный запрос, объединяющий EntityB и EntityC.

Возможно ли объединить это в один запрос?

class EntityA {
    @OneToMany(mappedBy = "entityALink", fetch = FetchType.EAGER)
    @JoinFetch
    private Collection<EntityB> entityBs;
}

class EntityB {
    @JoinColumn(name = "X", referencedColumnName = "Y")
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    private EntityA entityALink;

    @JoinColumn(name = "A", referencedColumnName = "B")
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinFetch
    private EntityC entityCLink;
}

class EntityC {

    @Id
    @Basic(optional = false)
    @Column(name = "SomeColumn")
    private String someField
}

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Сначала напишите запрос, чтобы получить EntityA.

EntityA entity = <your Query> ;

, затем позвоните

Collection<EntityB> entityB = entity.getEntityBs();
for(EntityB eachB : entityB){

    EntityC entityCLink = eachB.getEntityCLink();
}

Примечание : создание сеттеров и геттеров в каждой сущности.

0 голосов
/ 15 июля 2011

Если вам нужно уменьшить количество запросов, вы можете использовать отложенную инициализацию - FetchType.LAZY вместо FetchType.EAGER - таким образом jpa будет получать данные из баз данных при необходимости.Но вы должны помнить, что это не работает, когда объект отключен от менеджера.Поэтому, если вы отправляете эту сущность на другие серверы в сериализованной форме (например, в многоуровневом приложении), вы должны снова связать эту сущность с менеджером.Если ваше приложение работает на одном сервере, то у вас нет этой проблемы.

Подведение итогов не является точным ответом на ваш вопрос, но может быть полезно для оптимизации этого кода.

Точный ответ на ваш вопрос: вы можете использовать именованные запросы, но затем запрос анализируется на sqlнативный запрос, и вы не уверены, что это работает так, как вы хотите.Но, может быть, вы можете использовать собственный метод запроса?

em.createNativeQuery("SELECT ... your queries") 

Для этого, пожалуйста, прочитайте об использовании аннотации @SqlResultSetMapping для настройки класса объекта результата ...

...