【问题标题】:How to build predicate for a List in spring queryDSL?如何在 spring queryDSL 中为 List 构建谓词?
【发布时间】:2020-09-23 07:17:19
【问题描述】:
    Service.java

    private String sid;
    private String serviceName;
    private List<Feature> feature;

    Feature.java

    private Long id;
    private String featureName;

我构建如下谓词

     import com.querydsl.core.BooleanBuilder;
     import com.querydsl.core.types.Predicate;

     BooleanBuilder booleanBuilder = new BooleanBuilder();
     booleanBuilder.and(QService.service.id.eq(id));
     booleanBuilder.and(QFeature.feature.usoc.eq(featureUsoc));

     Predicate predicate = booleanBuilder;

     serviceRepository.findAll(predicate);

当我查询 repo 时,我得到以下错误

nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: illegal attempt to dereference collection [{synthetic-alias}{non-qualified-property-ref}feature] with element property reference [featureName] [select service
from com.ws.app.model.Service service
where service.id = ?2 and feature.featureName = ?3]]

如果实体中的变量是List类型,如何建立谓词查询?

【问题讨论】:

    标签: spring-data-jpa querydsl


    【解决方案1】:

    您需要一个 JOIN 或关联路径的子查询:

    query().from(QService.service)
        .where(QService.service.id.eq(id))
        .where(query().from(QService.service.feature, QFeature.feature)
              .where(QFeature.feature.usoc.eq(featureUsoc))
              .exists())
        .fetch()
    

    加入:

    query().from(QService.service)
        .innerJoin(QService.service.feature, QFeature.feature)
        .on(QFeature.feature.usoc.eq(featureUsoc))
        .where(QService.service.id.eq(id))
        .fetch()
    

    【讨论】:

    • 这里 query() 是指 JPAQuery 还是 JPASubQuery ?有很多选择,你能给我导入吗?
    • 可以是JPAQuery。由于 QueryDSL 4,您不能直接实例化 JPASubQuery,而应该只使用 JPAQuery 进行子查询。
    • 我添加了,JPAQuery jpaQuery = new JPAQuery(); QService service = QService.service; QFeature feature = QFeature.feature; jpaQuery.from(QService.service) .innerJoin(QService.service.feature, QFeature.feature) .on(QFeature.feature.usoc.eq(featureUsoc)); booleanBuilder.and(service.feature.any().eq(jpaQuery)); 现在我得到“子查询返回超过 1 个值。”错误,我需要在里面输入但不知道如何应用。
    • 修复了“子查询返回超过 1 个值。”通过更改 booleanBuilder.and(service.feature.any().in(jpaQuery));,这里我添加 IN 而不是 eq
    • 我会避免使用any。它不会创建您可能想要的查询。试试booleanBuilder.and(QService.service.feature.in(JPAExpressions.selectFrom(QFeature.feature).where(QFeature.feature.usoc.eq(featureUsoc)) 不幸的是,Spring Data 在这里抽象了 QueryDSL 和 JPA。您需要知道您正在处理什么才能正确编写此类查询。我建议先在 QueryDSL/JPQL 中编写您的查询,然后再将其转换为 Spring Data,当您对正在处理的内容有所了解时。
    猜你喜欢
    • 2015-01-21
    • 2016-01-08
    • 1970-01-01
    • 2021-04-13
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 2015-10-28
    相关资源
    最近更新 更多