Как диагностировать hibernate: Почему запрос с EntityGraph не работает?
По вводным: есть два запроса, один с использованием fetch join, второй такой-же, но вместо fetch join используется EntityGraph Запрос c fetch join выглядит так:
var builder = session.getCriteriaBuilder(); var criteriaQuery = builder.createQuery(MarketOrderPhotoItem.class); var root = criteriaQuery.from(MarketOrderPhotoItem.class); var sellerSubjectJoin = root.fetch("sellerSubject", JoinType.LEFT); sellerSubjectJoin.fetch("user", JoinType.LEFT); sellerSubjectJoin.fetch("legalEntity", JoinType.LEFT); var sales = root.fetch("sales", JoinType.LEFT); sales.fetch("payment", JoinType.LEFT); // FETCH для OneToOne root.fetch("order", JoinType.LEFT); root.fetch("marketPhoto", JoinType.LEFT); Join<MarketOrderPhotoItem, MarketPhoto> marketPhotoJoin = root.join("marketPhoto", JoinType.LEFT); Join<MarketOrderPhotoItem, MarketSale> salesJoin = root.join("sales", JoinType.LEFT); Join<MarketSale, MarketPayment> paymentJoin = salesJoin.join("payment", JoinType.LEFT); Join<MarketPayment, MarketUser> paymentUserJoin = paymentJoin.join("user", JoinType.LEFT); criteriaQuery.where( builder.and( root.get("status").in(statuses), marketPhotoJoin.get("id").in(photoId), paymentUserJoin.get("id").in(userId) ) ); criteriaQuery.orderBy(builder.asc(root.get("id"))); criteriaQuery.distinct(true);
Запрос с EntityGraph:
var builder = session.getCriteriaBuilder(); var criteriaQuery = builder.createQuery(MarketOrderPhotoItem.class); var root = criteriaQuery.from(MarketOrderPhotoItem.class); var graph = session.createEntityGraph(MarketOrderPhotoItem.class); graph.addAttributeNodes("sellerSubject", "sales", "order", "marketPhoto"); Subgraph<MarketSubject> sellerSubgraph = graph.addSubgraph("sellerSubject"); sellerSubgraph.addAttributeNodes("user", "legalEntity"); Subgraph<MarketSale> salesSubgraph = graph.addSubgraph("sales"); //Subgraph<MarketPayment> paymentSubgraph = salesSubgraph.addSubgraph("payment"); //paymentSubgraph.addAttributeNodes("user"); Join<MarketOrderPhotoItem, MarketPhoto> marketPhotoJoin = root.join("marketPhoto", JoinType.LEFT); Join<MarketOrderPhotoItem, MarketSale> salesJoin = root.join("sales", JoinType.LEFT); Join<MarketSale, MarketPayment> paymentJoin = salesJoin.join("payment", JoinType.LEFT); Join<MarketPayment, MarketUser> paymentUserJoin = paymentJoin.join("user", JoinType.LEFT); criteriaQuery.where( builder.and( root.get("status").in(statuses), marketPhotoJoin.get("id").in(photoId), paymentUserJoin.get("id").in(userId) ) ); criteriaQuery.orderBy(builder.asc(root.get("id"))); criteriaQuery.distinct(true); var typedQuery = session.createQuery(qr.criteriaQuery); typedQuery.setHint("javax.persistence.loadgraph", graph);
По вводным: если во втором запросе раскомментировать две закомментированные строки, он начинает выдавать:
query specified join fetching,
but the owner of the fetched association was not present in the select list
Сейчас ситуация такая: в чем может быть проблема? Hibernate версии 5.6.15 Находил похожие вопросы, но там либо использовался DTO-конструктор в select, либо запрос строился спрингом и он добавлял fetch к запросу с count. Не то не другое для меня не релевантно, однако ошибка такая же... Голову уже сломал. А мне нужен именно EntityGraph
По вводным: на всякий случай приведу сокращенные маппинги без лишнего:
@Entity @Table(name = "market_orderitem") @Inheritance(strategy = InheritanceType.JOINED) abstract public class MarketOrderItem { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "seller_subject", nullable = true) protected MarketSubject sellerSubject; // обратная ссылка на MarketSale @ManyToMany(mappedBy="orderItems", fetch = FetchType.LAZY) protected Set<MarketSale> sales; } @Entity @Table(name = "market_order_photo") @PrimaryKeyJoinColumn(name = "id") public class MarketOrderPhotoItem extends MarketOrderItem { @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "market_photo_id", nullable = false) private MarketPhoto marketPhoto; } @Entity @Table(name = "market_sale") public class MarketSale { // ссылка на MarketOrderItem @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinTable(name = "sale_items", joinColumns = {@JoinColumn(name = "sale_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "order_item_id", referencedColumnName = "id") }) protected Set<MarketOrderItem> orderItems = new HashSet<>(); @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "payment", nullable = true) private MarketPayment payment; }
По вводным: sales объявлен как many-to-many, а payment внутри sales как one-to-one. Ничего особо необычного. Единственное, что используется @Inheritance, но ведь запрос с fetch join при этом спокойно работает...
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос