【问题标题】:QueryDsl Projections leave a field blankQueryDsl Projections 将字段留空
【发布时间】:2021-04-01 07:55:36
【问题描述】:
@Entity
public class DocumentConsolidated {
    @Id private UUID id;

    @OneToOne(fetch = FetchType.EAGER, optional = false, cascade = CascadeType.ALL)
    @JoinColumn(name = "metadata_id")
    private DocumentMetadata documentMetadata;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "documentConsolidated")
    private DocumentConfiguration documentConfiguration;
}

@Entity
public class DocumentConfiguration {
    @Id private UUID id;

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    private DocumentConsolidated documentConsolidated;
}

// Service code:
QDocumentConsolidated qDoc = QDocumentConsolidated.documentConsolidated;
(JPQLQueryFactory) queryFactory
        .select(Projections.fields(qDoc, /*qDoc.id, */qDoc.documentConfiguration, qDoc.documentMetadata))
        .from(qDoc)
        .innerJoin(qDoc.documentConfiguration)
        .fetch();

这只有两种方式:

  • 带有 qDoc.idid 存在,documentConfiguration 为空
  • 没有 qDoc.idid 为空,documentConfiguration 存在

为什么?

我已经检查过的内容:当我在 Postgres 客户端中运行 Hibernate 查询时,它总是带来 documentConfiguration 字段。 Bot documentMetadata 在这两种情况下都存在。

【问题讨论】:

  • 我在这里大声思考,可能很离谱,但在这里。 querydsl Q 类表示表,并将所有列及其数据类型映射到 Java 数据类型。所以QDocumentConsolidated 不知道QDocumentConfiguration,因为QDocumentConfiguration 具有QDocumentConsolidated 的FK。 JPA 不在其中,Q 文件只有值,而不是复杂对象。因此,QDocumentConsolidated 的 FK 将是 NumberPath<Long> 而不是 DocumentConsolidated 实例。您是否尝试过投影到包含您需要的字段的 Java bean 中?
  • 嘿@RobertBain!抱歉回复晚了。不确定bean映射是什么意思。如果您的意思是Projections.bean(...) 我已经测试过,documentConfiguration 仍然为空。当使用Projections 创建查询时,我怀疑问题来自某些 ID 或数据冲突,并且它不知道如何取回数据。我设法通过使用简单的实体来解决这个问题 - 请参阅我的答案。

标签: java projection querydsl


【解决方案1】:

问题没有解决,但我通过从组合中删除 Projections 来解决它:

// Service code:
QDocumentConsolidated qDoc = QDocumentConsolidated.documentConsolidated;
QDocumentConfiguration qCfg = qDoc.documentConfiguration;
QDocumentMetadata qMeta = qDoc.documentMetadata;

return queryFactory
        .select(qDoc, qCfg, qMeta) // <-- get rid of Projections
        .from(qDoc)
        .innerJoin(qCfg) // <-- manual join on Lazy entity (qMeta is auto-joined)
        .fetch().stream()
        .map(tuple -> { // <-- entity creation, similar with Projections.bean()
            DocumentConsolidated documentConsolidated = Objects.requireNonNull(tuple.get(qDoc));
            documentConsolidated.setDocumentMetadata(tuple.get(qMeta));
            documentConsolidated.setDocumentConfiguration(tuple.get(qCfg));
            return documentConsolidated;
        })
        .collect(Collectors.toList());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-14
    • 2016-04-03
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    相关资源
    最近更新 更多