java - Hibernate/JPQL:如何根据对子项的查询加载所有子项的父项
问题描述
所以我们有一个简化了这两个实体的服务
@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() 访问票证。结果查询看起来很疯狂,我不确定这是否是一个聪明的方法。
解决方案
您可以使用JPA 方法进行@EntityGraph
获取和查询grants
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);
推荐阅读
- c++ - CGAL seam_mesh:如何在边界的 halfedge_descriptor 中包含接缝?
- spring-webflux - 如何根据反应堆上下文更改 url webClient
- c++ - 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- symfony - 教义:迁移:迁移。元数据存储不是最新的,请运行 sync-metadata-storage 命令修复此问题
- swift - 在 SwiftUI 中禁用模态表拖动手势
- c# - 查找 C Sharp 应用程序的入口点
- javascript - 匹配特定的 url 参数并返回其值
- java - JAVA - 类似运算符
- django - 带有附加标头的 Django 响应返回 500
- c# - Unity C# Player Prefs Highscore 不起作用