我在 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 选择?
经过挖掘和@Chris 的帮助,我找到了解决方案。
要实现左连接(并且仅左连接),重要的是在请求中使用连接的属性,而不是根类的属性。
`
Join
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));