首页 > 解决方案 > 如何加入仅获取选定的子实体与父实体

问题描述

我试图通过 id 只选择父级旁边的某些实体。这可能吗?示例(样板省略):

class Parent {
   int id;
   List<Child> children;
}

class Child {
   int id;
   ...
}

还有我的 JpaRepository:

interface ParentRepo extends JpaRepo<Parent,Integer> {
    @Query("SELECT p FROM Parent p JOIN p.children c WHERE p.id = :parentId and c.id IN(:childIds")
    Parent getParentByIdAndChildIds(int parentId, List<Integer> childIds)
}

我的期望是调用:

parentRepo.getParentByIdAndChildIds(1, Arrays.asList(1,2,3))

将返回仅附加 3 个子实体的父对象,但相反,我得到所有子对象(即 ID 为 1-10 的子对象)。

标签: javaspringjpaspring-datajpql

解决方案


那没有任何意义,因为需要获取整个实体图。考虑一个p有 children的父母c1c2并且只有和的c3id被传递给您的方法。如果您使用且仅获取一个实体,那么如果您执行以下操作会发生什么:c1c2Parentc1c2

p = parentRepo.getParentByIdAndChildIds(1, Arrays.asList(1,2));
p.getChildren().add(c3);
parentRepo.save(p); // what happens?

创建一个新的孩子没有意义,因为数据库中已经存在一个。另一方面,jpa 的默认行为将删除pc3保存时之间的关系而不修改:

p = parentRepo.getParentByIdAndChildIds(1, Arrays.asList(1,2));
parentRepo.save(p); // is the relationship between p and c3 destroyed

考虑创建双向关系(也从Childto Parent)并Child仅获取实体(from ChildRepository):

interface ChildRepository extends JpaRepository<Child, Integer> {
    @Query("SELECT c FROM Child c WHERE c.parent.id = :parentId and c.id IN(:childIds)")
    List<Child> getParentByIdAndChildIds(int parentId, List<Integer> childIds)
}

这样你只能得到Child你想要的实体,但也Parent可以从任何Child( children.get(0).getParent()) 访问。


推荐阅读