提问者:小点点

spring jpa中包含筛选子句的OneToMany问题


当在spring JPA中使用@OneTomany关系时,我目前在MySQL8/H2测试用例中得到了意想不到的结果。 我想使用JPQL在TKBData表中筛选TKBColumn-tables列表。 我希望得到一个带有过滤后的TKBColumn的TKBData-table,但我总是得到带有所有TKBColumn(未过滤)的TKBData-table。 当我使用一个SQL命令时,它是工作的!

我不知道这里有什么问题,为什么它总是给我TKBData-table,里面总是所有tkbcolumn-table。

本机查询(此操作有效):

SELECT d.id,c.name FROM TKBDATA d LEFT JOIN TKBDATA_TKBCOLUMN dc ON d.ID = dc.TKBDATA_ID LEFT JOIN TKBCOLUMN c ON c.ID = dc.COLUMNS_ID WHERE c.name =  'column1';

输出量

ID      NAME  
7b6ec910-3e53-40a3-9221-ee60e75c8d67    column1

JPQL查询(无效):

select d from TKBData d LEFT JOIN d.columns c WHERE c.name = :name

输出:

id: e892bc28-c35f-4fc8-9b09-387f97a758d8, name:column1
id: 069cc76b-3487-4ad8-a4ae-6568694e2287, name:column2

表“TKBData”

public class TKBData {

    @Id
    @Builder.Default
    private String id = UUID.randomUUID().toString();

    ...

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @Builder.Default
    private Set<TKBColumn> columns = Sets.newHashSet();
    
    ...
}

表“TKBColumn”

public class TKBColumn {

    @Id
    @Builder.Default
    private String id = UUID.randomUUID().toString();
    
    ...
}

spring数据储存库

@Service
public interface KBDataRepository extends CrudRepository<TKBData, String>, KBDataCustomRepository {

    @Query("select d from TKBData d LEFT JOIN d.columns c WHERE c.name = :name")
    public TKBData filterByColumn(@Param("name") String name);

}

有关更多信息,您可以在这里找到github存储库:https://github.com/fo0/scrumtool/blob/master/scrumtool/src/Test/Java/com/fo0/vaadin/scrumtool/Test/data/tkbDataColumnFilterTest.Java


共1个答案

匿名用户

>

  • 当谈到JPA查询语言时,我想把qurey看作是内存中对象的集合。

    所以现在试着说明下面两个查询在对象中的含义。

    select d from TKBData d LEFT JOIN d.columns c WHERE c.name = :name
    

    vs

    select d from TKBData d JOIN d.columns c WHERE c.name = :name
    

    >

  • 不要忘记,与sql中选择任何列不同,您在这里表示要选择TKBData对象,并限制返回哪些TKBData对象。

    因此,要实现与本机sql相同的结果,请使用第二个JPA查询

    注意:同样值得指出的是,即使您在sql查询中通过对最右边的表应用where条件而使用了左联接,但它实际上是一个内部联接sql查询