Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa 从多个不同实体收集所有子实体_Jpa_Eclipselink_Jpql_Criteria Api_Javax.persistence - Fatal编程技术网

Jpa 从多个不同实体收集所有子实体

Jpa 从多个不同实体收集所有子实体,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

我有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_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保持警惕,因为它可能不太理想。

谢谢您提供的信息。我将尝试双向链接。(我将把这个问题保留一段时间,但如果没有人回答,我会接受你的答案)谢谢你提供的信息。我将尝试双向链接。(我将把这个问题保留一段时间,但如果没有人回答,我会接受你的答案)