【问题标题】:QueryDSL how do I create a SubQuery with its own joins?QueryDSL 如何创建带有自己连接的子查询?
【发布时间】:2020-05-14 13:06:35
【问题描述】:

我正在尝试为在 BooleanExpression 中使用 exists 子句的 QueryDSL 选择构建子查询。

数据模型是这样的,即存在包含单个媒体的项目。媒体可以有很多维度。我正在寻找具有特定维度数据并使用子查询来完成的项目。

子查询如下所示:

QProject project = QProject.project;
QMedia media = QMedia.media;

Predicate subExpression = JPAExpressions.selectOne()
            .from(media)
            .innerJoin(media.dimensions)
            .where(project.media.id.eq(media.id),
                dimension.dimensionType.id.eq(Long.valueOf(inputDimensionType))).exists();

我将其存储为谓词,但是当我尝试在父查询中使用它时出现错误:antlr.NoViableAltException: unexpected token: elements

导致错误的生成部分看起来像这样(来自 hibernate.hql.internal 日志):

... and ((exists (select 1
from com.app.model.Media media
  inner join elements(media.dimensions)

这是当我将它插入到这样的主查询中时发生的错误:

JPAQuery<ResponseCurve> query = new JPAQuery<>(this.entityManager);
query.select().from(project)
  .where(project.state.eq(inputState))
  .where(subExpression);

【问题讨论】:

  • 我已经删除了我的答案,因为我误解了子查询在做什么,我的错。出于好奇,如果您有 QDimension dimension = QDimension.dimension 并调用 .innerJoin(media.dimensions, dimension) 而不是当前存在的 .innerJoin(media.dimensions) 会发生什么?

标签: java hibernate querydsl


【解决方案1】:

这个查询有两个可能的问题:

  1. 您正在尝试引用别名 dimensions,但您从未将其与 media.dimensions 的联接相关联
  2. 您正在取消引用 dimension.dimensionType 而没有加入。对于标识符值,这是可能的,对于任何其他属性,则不是。

怎么样:

QProject project = QProject.project;
QMedia media = QMedia.media;
QDimension dimension = QDimension.dimension;

Predicate subExpression = JPAExpressions.selectOne()
        .from(project.media, media)
        .innerJoin(media.dimensions, dimension )
        .on(dimension.dimensionType.id.eq(Long.valueOf(inputDimensionType))

【讨论】:

  • 感谢您的回答。我无法将JPAExpressions 分配给Predicate 对象,它似乎会生成JPQLQuery&lt;Tuple&gt;。你知道为什么吗?
  • 我从您的原始查询中复制了它,但我似乎错过了最后的“exists()”调用。
  • 非常感谢。我不是 OP 虽然只是为了清楚。
猜你喜欢
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多