Jpa 从多个不同实体收集所有子实体
我有3个实体A、B和CJpa 从多个不同实体收集所有子实体,jpa,eclipselink,jpql,criteria-api,javax.persistence,Jpa,Eclipselink,Jpql,Criteria Api,Javax.persistence,我有3个实体A、B和C A包含一对一链接的B实体 A包含C实体的一对多链接列表 B包含C实体的一对多链接列表 数据库方面有5个表。3个表分别用于各自的实体和2个单独的链接表,一个包含A和C之间的链接(A_至C),另一个包含B和C之间的链接(B_至C)。 在我的存储库中,我试图从一个特定的a记录中检索所有C实体,这意味着从a本身检索C实体以及通过B链接的C实体 在传统SQL中,这可以使用以下方法完成: select C.* from A left join A_to_C on A_to_C.A
- A包含一对一链接的B实体
- A包含C实体的一对多链接列表
- B包含C实体的一对多链接列表
select C.*
from A
left join A_to_C on A_to_C.A_ID = A.ID
left join B_to_C on B_to_C.B_ID = A.B_ID
inner join C on C.ID = A_to_C.C_ID OR C.ID = B_to_C.C_ID
where A.ID = '1';
或(从C开始)
在这些SQL示例中,没有指向B的表的链接,因为A包含B的ID,它也是B_to_C中使用的ID,所以我并不真正需要它。我也知道这两者并不完全相同,但当我只对C感兴趣时,它们会产生相同的结果
我真的很难在CriteriaBuilder(最好)或JPQL中实现这一点。
我对jpa还比较陌生,所以我希望这里的人能帮我解决这个问题。我相信,要想成功使用香草JPQL,你需要通过添加
@ManyToOne
端,将关联转换为双向关联(或单向多对一)。然后可以从C
开始查询。在这种情况下,@OneToMany
端(如果您想保留它)将成为关联的反面,不过:
@Entity
public class C {
@ManyToOne
@JoinTable
private B b;
@ManyToOne
@JoinTable
private A a;
}
@Entity
public class B {
@ManyToOne
@JoinTable
private A a;
@OneToMany(mappedBy = "b")
private List<C> cs;
}
@Entity
public class A {
@OneToMany(mappedBy = "a")
private List<B> bs;
@OneToMany(mappedBy = "a")
private List<C> cs;
}
如果你不同意将关联的“一”面变成相反的一面,那么你就不走运了。最简单的解决方案是使用本机查询
Eclipselink JPQL扩展包含一个ON
子句,因此您可以将ON
与的成员组合使用:
SELECT c FROM C c
LEFT JOIN A a ON c MEMBER OF a.cs
LEFT JOIN B b ON c MEMBER OF b.cs
LEFT JOIN A a2 ON b MEMBER OF a2.cs
WHERE a.id = :id OR a2.id = :id
不过,我非常怀疑它是否会起作用,即使它起作用,我也会对生成的SQL保持警惕,因为它可能不太理想。我相信,要想成功使用香草JPQL,您需要将关联转换为双向关联(或单向多对一)通过添加@ManyToOne
侧。然后可以从C
开始查询。在这种情况下,@OneToMany
端(如果您想保留它)将成为关联的反面,不过:
@Entity
public class C {
@ManyToOne
@JoinTable
private B b;
@ManyToOne
@JoinTable
private A a;
}
@Entity
public class B {
@ManyToOne
@JoinTable
private A a;
@OneToMany(mappedBy = "b")
private List<C> cs;
}
@Entity
public class A {
@OneToMany(mappedBy = "a")
private List<B> bs;
@OneToMany(mappedBy = "a")
private List<C> cs;
}
如果你不同意将关联的“一”面变成相反的一面,那么你就不走运了。最简单的解决方案是使用本机查询
Eclipselink JPQL扩展包含一个ON
子句,因此您可以将ON
与的成员组合使用:
SELECT c FROM C c
LEFT JOIN A a ON c MEMBER OF a.cs
LEFT JOIN B b ON c MEMBER OF b.cs
LEFT JOIN A a2 ON b MEMBER OF a2.cs
WHERE a.id = :id OR a2.id = :id
不过,我非常怀疑它是否会起作用,即使它起作用,我也会对生成的SQL保持警惕,因为它可能不太理想。谢谢您提供的信息。我将尝试双向链接。(我将把这个问题保留一段时间,但如果没有人回答,我会接受你的答案)谢谢你提供的信息。我将尝试双向链接。(我将把这个问题保留一段时间,但如果没有人回答,我会接受你的答案)