JPA OneToMany关联下对子表排序限制并投影的实现方案
结论
完全可以通过JPQL查询或者JPA方法命名约定实现需求,以下是具体实现方案:
前置修正
你当前定义的ParentRepository存在泛型参数错误:Parent实体的主键类型是Long,因此继承JpaRepository时第二个泛型参数需要改为Long而非UUID。
同时你的MyProjection作为封闭投影,需要明确定义和查询字段匹配的getter方法:
interface MyProjection { // 方法名和JPQL查询的字段别名一一对应 fun getParentId(): Long? fun getChildId(): Long? fun getVersion(): Int? fun getData(): String? }
方案1:JPQL实现(更推荐,可读性更高)
直接在ParentRepository中定义查询即可,Spring Data JPA会自动完成投影映射、排序、取第一条的逻辑:
@Repository interface ParentRepository : JpaRepository<Parent, Long> { @Query(""" select p.id as parentId, c.id as childId, c.version as version, c.data as data from Parent p join p.children c where p.id = :parentId order by c.version desc """) fun findWithLatestChild(parentId: Long?): MyProjection? }
如果你的JPA实现不支持自动识别单条返回加限制,可以在select后加top 1适配:select top 1 p.id as parentId, ...
方案2:JPA方法命名约定实现
如果不想手动写JPQL,也可以通过符合命名规则的方法名实现,更推荐在ChildRepository中定义,逻辑更直观:
@Repository interface ChildRepository : JpaRepository<Child, Long> { // Top 代表仅返回第一条,ByParentId按父ID过滤,OrderByVersionDesc按version降序 fun findTopByParentIdOrderByVersionDesc(parentId: Long?): MyProjection? }
如果一定要在ParentRepository中用方法命名实现,写法如下(可读性稍差):
fun findTopByIdOrderByChildrenVersionDesc(id: Long?): MyProjection?
内容的提问来源于stack exchange,提问作者larsw
相关产品推荐
相关产品推荐

