使用 JPA 和 Criteria Builder 在 @OneToMany 关系中选择父级并仅选择子级的某些字段

问题描述 投票:0回答:1

实现一对多关系并选择父子关系。 使用条件生成器,我需要获取父级和所有相关的子级,但仅从每个子级中选择一些字段。

@Entity
@Table(name="transaction_status")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TransactionStatus implements Serializable {
@Id
@Column(name = "id")
@JsonProperty("id")
public String id;

@SerializedName("status")
public String status;

@Column(name="lastUpdatedDate")
@JsonProperty("lastUpdatedDate")
@SerializedName("lastUpdatedDate")
private Date lastUpdatedDate;

@JsonProperty("generatedAt")
@SerializedName("generatedAt")
@JsonIgnore
private Date generatedAt;

@JsonProperty("invoices")
@SerializedName("invoices")
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="transactionstatusId",referencedColumnName = "xmlFilename")
private List<InvoiceTransaction> invoiceTransactions = new ArrayList<>();

}

@Entity
@Table(name="invoice_transaction")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor

public class InvoiceTransaction implements Serializable {
    @Column(name = "status", nullable = false)
    @JsonProperty("status")
    @SerializedName("status")
    private String status;
    @Column(name = "originalStatus", nullable = false)
    @JsonProperty("originalStatus")
    @SerializedName("originalStatus")
    private String originalStatus;
    
    @Column(name = "errorMessage")
    @JsonProperty("errorMessage")
    @SerializedName("errorMessage")
    private String errorMessage;

    @Column(name = "generatedAt" )
    @JsonProperty("generatedAt")
    @SerializedName("generatedAt")
    private Date generatedAt;
}

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<TransactionStatus> cq = builder.createQuery(TransactionStatus.class);
Root<TransactionStatus> rootTrnStatus = cq.from(TransactionStatus.class);
List<TransactionStatus> resultList = entityManager.createQuery(cq).getResultList();

此实现为我提供了 Transactionstatus 对象列表及其子对象列表。我想要得到的是: Transactionstatus 对象的列表及其带有 olny 状态和 errorMessage 字段的子对象列表。我如何使用 Crititeria 生成器获得这个结果? 谢谢你

java spring spring-boot jpa criteria-api
1个回答
0
投票

要实现从子实体 (InvoiceTransaction) 中仅选择特定字段的所需结果,您可以使用 Criteria API 创建一个查询来检索父实体 (TransactionStatus) 以及子实体字段的投影。您可以通过以下方法修改 Criteria 查询来实现此目的:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Object[]> cq = builder.createQuery(Object[].class);

Root<TransactionStatus> rootTrnStatus = cq.from(TransactionStatus.class);
Join<TransactionStatus, InvoiceTransaction> joinInvoice = rootTrnStatus.join("invoiceTransactions", JoinType.LEFT);

cq.select(builder.array(rootTrnStatus, joinInvoice.get("status"), joinInvoice.get("errorMessage")));

List<Object[]> resultList = entityManager.createQuery(cq).getResultList();

List<TransactionStatus> transactionStatusList = new ArrayList<>();
for (Object[] result : resultList) {
    TransactionStatus transactionStatus = (TransactionStatus) result[0];
    InvoiceTransaction invoiceTransaction = new InvoiceTransaction();
    invoiceTransaction.setStatus((String) result[1]);
    invoiceTransaction.setErrorMessage((String) result[2]);
    transactionStatus.getInvoiceTransactions().add(invoiceTransaction);
    transactionStatusList.add(transactionStatus);
}
© www.soinside.com 2019 - 2024. All rights reserved.