当在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
>
当谈到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查询