Использование Entity Graph в Java

Entity Graph позволяет определить, как JPA должен загружать связи при запросе определенной сущности. Это позволяет разработчикам указывать, какие связанные объекты следует загружать быстро, а какие — лениво. Entity Graph можно определить с помощью аннотации @NamedEntityGraph в классе сущностей. Эта аннотация указывает имя графа сущности и атрибуты, которые должны быть включены в граф.


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


Можно определить несколько графов сущностей для одного класса, используя разные имена для каждого графа и указав соответствующее имя графа при использовании метода setHint для объекта запроса.


Пример использования графов сущностей в Java: Предположим, у нас есть две сущности: Order и Item, где order может содержать несколько позиций.

@Entity
public class Order {
    @Id
    private Long id;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
    private List<Item> items;
}

@Entity
public class Item {
    @Id
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private Order order;

    private String name;
}

Мы можем создать граф сущностей для получения всех заказов со связанными с ними элементами:

@Entity
@NamedEntityGraph(name = "Order.items", attributeNodes = @NamedAttributeNode("items"))
public class Order {
    // ...
}

Затем мы можем использовать этот граф сущностей для получения заказов со связанными с ними элементами с помощью методов createEntityGraph() и setHint():

EntityManager em = // obtain entity manager
EntityGraph<Order> graph = em.createEntityGraph(Order.class);
graph.addAttributeNodes("items");

List<Order> orders = em.createQuery("SELECT o FROM Order o")
                        .setHint("javax.persistence.fetchgraph", graph)
                        .getResultList();

Это позволит получить все заказы со связанными с ними товарами в одном запросе.