Получение данных из объединений нескольких таблиц с использованием Spring и Hibernate - PullRequest
0 голосов
/ 28 июня 2019

У меня есть несколько сущностей и репозиториев Spring с цепочкой ассоциаций:

Root -> Foo -> Bar -> Qux -> ...

Примерно так:

class Root {
    private String rootData;
    @OneToOne
    private Foo foo;
}

class Foo {
    private String fooData;
    @OneToOne
    private Bar bar;
}

class Bar {
    private String barData;
    @OneToOne
    private Qux qux;
}

class Qux {
    private String quxData;
    @OneToOne
    private GoesOn goesOn;
}

Существуют сотни тысяч корневых объектов, и все ассоциации ленивы.

Мне нужно создать отчет со списком всех корневых объектов с данными follogwing:

  • rootData
  • fooData
  • barData
  • quxData

Если я попытаюсь заполнить отчет, просматривая ассоциации, будет больше N запросов к базе данных для каждого корневого объекта.

Есть ли способ получить все данные одним запросом, используя объединения, не изменяя связи на активные?

Ответы [ 3 ]

0 голосов
/ 28 июня 2019

Вы можете использовать HQL или JOINS SELECT t1, t2 ОТ Table1 t1, Table2 t2, ГДЕ t1.x = t2.x

0 голосов
/ 02 июля 2019

@ Ответ Антониоссса решил это за меня.

После еще одного тестирования и на основе этой статьи мне удалось сделать это с более простым решением, без NamedEntityGraph.Я создал функцию в своем интерфейсе RootRepository со следующим:

@EntityGraph(attributePaths = {"foo.bar.qux"})
List<Root> findAllEagerJoin(Specification<Root> spec);

Запрос атрибута в конце цепочки ассоциации вызвал объединение всех таблиц.

0 голосов
/ 28 июня 2019

Вы можете использовать граф сущностей, чтобы указать, какие свойства должны быть извлечены напрямую (eagar way)

Вы аннотируете одну из своих сущностей с помощью

@NamedEntityGraph(
  name = "report-eg",
  attributeNodes = {
    @NamedAttributeNode("foo"),
    @NamedAttributeNode(value = "bar", subgraph = "bar-eg"),
  },
  subgraphs = {
    @NamedSubgraph(
      name = "bar-eg",
      attributeNodes = {
        @NamedAttributeNode("qux")
      }
    )
  }
)

И затем вы используете его в выборке

EntityGraph entityGraph = entityManager.getEntityGraph("report-eg");
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.loadgraph", entityGraph);
Post post = entityManager.find(Foo.class, id, properties);

Очевидно, что вам, вероятно, придется настроить этот график для ваших нужд, но он покажет вам путь.

В качестве альтернативы, вы можете использовать Criteria API. Это позволяет напрямую указать, какие отношения должны быть fetched (в отличие от объединения)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...