Java 缺少内部连接ON子句的JPA和Hibernate

Java 缺少内部连接ON子句的JPA和Hibernate,java,hibernate,jpa,Java,Hibernate,Jpa,我正试图找出我在JPA/Hibernate上犯了什么错误 我有一个包含两个表的数据库:banner和bannerlinks banner +-------------------------------------------+ | id | logo | studyId | textColor | bgColor | +-------------------------------------------+ | 1 | xx | 17 | green | re

我正试图找出我在JPA/Hibernate上犯了什么错误

我有一个包含两个表的数据库:banner和bannerlinks

 banner
 +-------------------------------------------+
 | id | logo | studyId | textColor | bgColor |
 +-------------------------------------------+
 |  1 | xx   |  17     |  green    | red     |
 +-------------------------------------------+

 bannerlink
 +----------------------------------------+
 | id | bannerId| label | text | image    |
 +----------------------------------------+
 |  1 | 1       |  About| Abt..| xxx      |
 +----------------------------------------+
 |  2 | 1       |  Beta | Bet..| xxx      |
 +----------------------------------------+
 |  2 | 1       |  Cont | Ctc..| xxx      |
 +----------------------------------------+
和实体类

@Entity
@Table(name="bannerlink")
public class BannerLink{
    @Id
    @GeneratedValue
    private int id;
    private String label;

    @ManyToOne
    @JoinColumn(name = "bannerId")
    private Banner banner;
    ...
}


@Entity
@Table(name = "banner")
public class Banner {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String logo;
    private String textColor;
    private String backgroundColor;
    private int studyId;

    @OneToMany(
        mappedBy = "banner",
        cascade = CascadeType.ALL,
        fetch=FetchType.LAZY,
        targetEntity = BannerLink.class
    )
    private List<BannerLink> links;

    public Banner() {
    }
    ...
 } 

知道我做错了什么吗?

为什么需要加入,这是某种隐式过滤器吗?正如我看到的,studyId在Banner中,所以只需删除查询并将函数名更改为findOneByStudyId。还要删除Param注释。然后,如果您需要链接信息,只需调用getter即可,而不是延迟获取。 但如果您需要加入,我会这样写(未经测试):
从Banner b中选择DISTINCT b,Banner链接bl,其中b.studyId=:studyId

您的查询是错误的。正确的查询是>

"select distinct banner FROM Banner banner fetch join banner.links where banner.studyId = :studyId"

我理解你的问题的方式是,你想为一个studyId获取所有横幅及其相应的链接。如果我错了,请纠正我。上面的查询正在完成这项工作。

同意@kSp-如果您使用的是Spring Data JPA,则没有理由自己编写此查询,也没有理由使用它的功能根据方法名称生成查询。否则,如果您确实需要自己编写,请尝试使用适当的JPQL连接编写查询,例如


从横幅b中选择b加入b.links,其中b.studyId=:studyId

是!我花了好长时间才弄明白

有两种方式可以加入。如果在实体之间按现有方式连接,则必须指定要连接的属性。JPA不会猜的

所以你必须这样做:

@Query(“选择不同的b
从Banner b加入Banner链接b.id=bl.bannerId上的bl
其中b.studyId=:studyId”)
Banner getBannerByStudyId(@Param(“studyId”)int studyId)

但是,您几乎应该始终指定执行联接的父级的属性,即子级集合的属性。 通过这种方式,您可以告诉JPA如何连接表,您只需要给它Where子句:

@Query(“选择不同的b
从横幅b加入b链接bl
其中b.studyId=:studyId”)
Banner getBannerByStudyId(@Param(“studyId”)int studyId)

参考:

 Hibernate: 
     select
         distinct banner0_.id as id1_0_,
         banner0_.backgroundColor as backgrou2_0_,
         banner0_.logo as logo3_0_,
         banner0_.studyId as studyId4_0_,
         banner0_.textColor as textColo5_0_ 
     from
         banner banner0_ 
     inner join
         bannerlink bannerlink1_ 
             on 
     where
         banner0_.studyId=?
"select distinct banner FROM Banner banner fetch join banner.links where banner.studyId = :studyId"