JPA CriteriaBuilder:列出带有约束的内部类列表的顶级类

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

我在 3 个实体(发票和 InvoiceRating 以及用户)之间有关系 我无法生成按特定用户的评级排序的发票列表。即使没有评级,发票也应该列出(用户只是过滤评级的参数)

{
  invoiceA :
   rating:2
   others fields
  invoiceB : 
   rating:3
   others fields
  invoiceC :
   others fields
}
@Entity
public class Invoice  {
 @OneToMany(mappedBy = "invoice", fetch = FetchType.LAZY)
  Set<InvoiceRating> ratings;
}
@Entity
public class InvoiceRating {
    @EmbeddedId
    BusinessTransactionRating ratingKey;

    @ManyToOne
    @MapsId("userId")
    @JoinColumn(name = "user_id")
    User user;

    @ManyToOne
    @MapsId("transactionId")
    @JoinColumn(name = "invoice_id")
    Invoice invoice;

    int rating;
}
@Embeddable
public class BusinessTransactionRating {
    @Column(name = "transaction_id")
    Long transactionId;

    @Column(name = "user_id")
    Long userId;

}
@Entity
public class User {
}

有效的代码:

CriteriaQuery<Invoice> criteriaQuery = cBuilder.createQuery(Invoice.class);
Root<Invoice> rootInvoice = criteriaQuery.from(Invoice.class);

pageable.getSort().stream().forEach(order -> { // sorting
         Path<Object> prop = rootInvoice.get(order.getProperty());
     list.add(order.isAscending() ? cBuilder.asc(prop) : cBuilder.desc(prop));
            // finalQuery.orderBy();
        });
CriteriaQuery<Invoice> criteriaQueryOrder = finalQuery.orderBy(list);
        // TO DO / Add the count Line and the rebuild pageImpl
TypedQuery<Invoice> queryPaginate = entityManager.createQuery(criteriaQueryOrder);

我需要做什么来添加由用户过滤的 InvoiceRating 选择?

java spring-boot jpa constraints criteriabuilder
1个回答
0
投票

经过挖掘和@Chris 的帮助,我找到了解决方案。 要实现左连接(并且仅左连接),重要的是在请求中使用连接的属性,而不是根类的属性。 ` Join join = root.join(Invoice.Fields. ratings, JoinType.LEFT);

    Predicate invoiceSelection = cb.equal(root.get(BusinessTransaction.Fields.id),
            join.get(InvoiceRating.Fields.ratingKey)
                    .get(BusinessTransactionRating.Fields.transactionId));

    Predicate userSelection = (cb.equal(join.get(InvoiceRating.Fields.user), user));
    join.on(userSelection, invoiceSelection);

`

join.get(InvoiceRating.Fields.user) -> 而不是 root.get(BusinessTransaction.Fields.id), join.get(InvoiceRating.Fields_user).

在从根开始实现get的情况下,也实现了Join,结果不同。您将收到 2 个连接的请求 -> 加入 .... 加入左侧,这不是您想要的。 然后你就可以做:

cq.where(query).distinct(true).orderBy((orderBylist))
.select(cb.array(join.get(InvoiceRating.Fields.rating), rootInvoice));

注意:对于订购,您还必须指定连接的评级

Path<Object> prop = join.get(InvoiceRating.Fields.rating);
orderBylist.add(order.isAscending() ? cb.asc(prop) : cb.desc(prop));
© www.soinside.com 2019 - 2024. All rights reserved.