Hibernate / JPQL: как загрузить родительский элемент со всеми дочерними элементами на основе запроса дочернего элемента - PullRequest
0 голосов
/ 05 мая 2020

Итак, у нас есть сервис с упрощенными этими двумя сущностями

@Entity
public class Ticket {
/* simplified*/

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
  private Set<Grant> grants = new HashSet<>();
}

@Entity
public class Grant {
/* simplified*/

  @NotNull
  @ManyToOne(fetch = LAZY)
  @JoinColumn(name = UsageGrant.FK_TICKET, nullable = false)
  private Ticket ticket;

  @NotNull
  @Column(name = "specialNumber", nullable = false)
  private Integer specialNumber;
}

Я хотел бы иметь запрос, который выбирает все билеты, которые содержат грант с определенным c "specialNumber". Загвоздка в том, что я хочу, чтобы билет возвращался со всеми грантами, а не только с одним подходящим. Я пробовал это с

@Repository
public interface TicketRepository extends JpaRepository<Ticket, String> {

@Query("SELECT DISTINCT ti FROM Ticket ti JOIN FETCH ti.grants g WHERE 
g.specialNumber = :specialNumber "
  )
  List<Ticket> findBySpecialNumberAndLoadAllGrantsOnTicket(
      @NotNull @Param("specialNumber") Integer specialNumber);
}

, но это дает мне только подходящий. Нужно ли мне разбивать его на два запроса? Criteria API также не помогает, потому что RIGHT JOIN там также не поддерживается.

Обновление

Я могу добиться этого с помощью

SELECT g FROM Grant g LEFT JOIN FETCH g.ticket ti JOIN FETCH ti.grants WHERE g.specialNumber = :specialNumber

и доступ к билету с помощью g.getTicket (). Полученный запрос выглядит сумасшедшим, и я не уверен, что это вообще разумный подход.

1 Ответ

0 голосов
/ 05 мая 2020

Вы можете использовать @EntityGraph для выборки grants и запроса с использованием метода JPA для выбора specialNumber

@EntityGraph(attributePaths = {"grants"})
public List<Ticket> findByGrantsSpecialNumber(Integer specialNumber);

Или

Вы можете использовать @NamedEntityGraph

@NamedEntityGraph(name = "Ticket.Grants", attributeNodes = { @NamedAttributeNode("grants") })
public class Ticket {

И

@EntityGraph(value = "Ticket.Grants", type = EntityGraphType.LOAD)
public List<Ticket> findByGrantsSpecialNumber(Integer specialNumber);
...