QueryDSL and ManyToMany relationships



在一个项目中,我有以下实体:模板有模板部分连接到关键字。这两个关系都是@ManyToMany。一些代码:

@NoArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "TEMPLATE")
public class TemplateEntity extends SystemFlagEntity {
...
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "TEMPLATEPART_CATALOGUE",
joinColumns = @JoinColumn(name = "C_FK_TEMPLATE", referencedColumnName = "C_I_IDF"),
inverseJoinColumns = @JoinColumn(name = "C_FK_TEMPLATEPART", referencedColumnName = "C_I_IDF"))
Set<TemplatePartEntity> templatePartsCatalogue = new HashSet<>();
}
@ToString
@NoArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "TEMPLATEPART")
public class TemplatePartEntity extends SystemFlagEntity {
...
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "TEMPLATEPART_KEYWORD",
joinColumns = @JoinColumn(name = "C_FK_TEMPLATEPART"),
inverseJoinColumns = @JoinColumn(name = "C_FK_KEYWORD"))
Set<KeywordEntity> keywords = new HashSet<>();
}
@NoArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "KEYWORD")
public class KeywordEntity extends LabeledEntity {
...
}

然后我尝试找到与某个给定ID的模板相关的关键字。我使用以下谓词对QueryDSL进行此操作:

public Iterable<KeywordEntity> findCatalogueKeywordsForTemplate(Long id) {
return findAll(
QKeywordEntity.keywordEntity.in(QTemplateEntity.templateEntity.templatePartsCatalogue.any().keywords)
.and(QTemplateEntity.templateEntity.id.eq(id))
);
}

由于某些原因,谓词根本不能很好地处理。当尝试调用

方法时,我得到了这个错误:

org.hibernate.hql.internal.ast.QuerySyntaxException:templateEntity。templatePartsCatalogue没有被映射[select]keywordEntity nfrommypackage.core.domain.model.KeywordEntity关键字实体n在哪里存在(选择1n从templateEntity。templatePartsCatalogue作为templateEntity_templatePartsCatalogue_0nwhere关键字实体成员templateEntity_templatePartsCatalogue_0.keywords)和templateEntity。Id = ?1];嵌套异常是java.lang.IllegalArgumentException:org.hibernate.hql.internal.ast.QuerySyntaxException:templateEntity。templatePartsCatalogue没有被映射[select]keywordEntity nfrommypackage.core.domain.model.KeywordEntity关键字实体n在哪里存在(选择1n从templateEntity。templatePartsCatalogue作为templateEntity_templatePartsCatalogue_0nwhere关键字实体成员templateEntity_templatePartsCatalogue_0.keywords)和templateEntity。Id = ?1]

看起来它不能很好地处理@ManyToMany关联。有什么办法解决这个问题吗?我知道我可以显式地使用JPAQuery,但我想使用Predicate代替。

在看到QueryDSL的创建者的这个答案后,我发现我误解了谓词的工作方式。此查询无需显式定义多对多关联表即可工作:

public Iterable<KeywordEntity> findCatalogueKeywordsForTemplate(Long id) {
return new JPAQuery<>(entityManager)
.select(QKeywordEntity.keywordEntity)
.from(QTemplateEntity.templateEntity)
.innerJoin(QTemplateEntity.templateEntity.templatePartsCatalogue, QTemplatePartEntity.templatePartEntity)
.innerJoin(QTemplatePartEntity.templatePartEntity.keywords, QKeywordEntity.keywordEntity)
.where(interceptPredicate(QTemplateEntity.templateEntity.id.eq(id)))
.distinct()
.fetch();
}

最新更新