HibernateJPQL。如何根据对子代的查询加载父代与所有子代的信息

问题描述 投票:0回答:1

因此,我们有一个简化了这两个实体的服务。

@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;
}

我想建立一个查询,选择所有包含具有特定 "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()访问票据。结果查询看起来很疯狂,我不知道这是不是一个聪明的方法。

java hibernate spring-boot jpql
1个回答
0
投票

你可以使用@EntityGraph来表示fetch。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);
© www.soinside.com 2019 - 2024. All rights reserved.