Tôi đã bật ghi nhật ký SQL và kiểm tra kết quả truy vấn. Đối với trường hợp trên, đó là:
/* load one-to-many com.prepaytec.pacasso.common.model.Card.purchaseProductGroups */
select
* /* the actual field list has been omitted for brevity */
from
pacasso.purchaseprodgrp_card purchasepr0_
inner join
pacasso.purchase_product_group purchasepr1_
on purchasepr0_.ppg_id=purchasepr1_.ppg_id
where
(
exists (
select
*
from
purchase_product_group ppg
where
ppg.ppg_id = purchasepr0_.ppg_id
AND ppg.ppg_status <> 'D'
)
)
and purchasepr0_.crd_id=?
Vì vậy, tham gia cần thiết đã được bao gồm và nó có vẻ như như tất cả những gì cần thiết là sau:
@Where(clause = "ppg_status <> 'D'")
Tuy nhiên, hóa ra không làm việc như Hibernate thêm bí danh bảng sai:
where
(
purchasepr0_.ppg_status <> 'D'
)
and purchasepr0_.crd_id=?
Rất tiếc khi bí danh được gán cho một bảng, bạn không thể sử dụng tên bảng gốc - vì vậy purchase_product_group.ppg_status <> 'D'
sẽ không hoạt động. Và tôi không biết cách xác định tên bí danh được Hibernate sử dụng theo chương trình - vì vậy hiện tại lựa chọn có vẻ là mã cứng tên bí danh được Hibernate sử dụng (tức là purchasepr1_.ppg_status <> 'D'
) hoặc để sử dụng exists
phương pháp được mô tả trong câu hỏi.
CẬP NHẬT: Khi điều tra sâu hơn, nó chỉ ra rằng mã hóa cứng các tên bí danh không phải lúc nào cũng khả thi. Đây là một truy vấn tiêu chí mà điều này sẽ không hoạt động:
/* criteria query */
select
* /* the actual field list has been omitted for brevity */
from
pacasso.merchant_acquirer this_
left outer join
pacasso.purchaseprod_merchant_acquirer purchasepr2_
on this_.mac_id=purchasepr2_.mac_id
and (
// This wouldn't work with any alias since the required
// table is pacasso.purchase_product purchasepr3_, which
// is joined below.
purchasepr2_.ppr_status <> 'D'
)
left outer join
pacasso.purchase_product purchasepr3_
on purchasepr2_.ppr_id=purchasepr3_.ppr_id
where
this_.mac_code=?
and this_.cst_id=?
Cuối cùng, tôi đã từ bỏ @Where
cách tiếp cận và sử dụng @Filter
thay vào đó, điều này có vẻ tốt hơn nhiều vì nó có thể chấp nhận HQL hơn là tên trường cơ sở dữ liệu và khi được áp dụng ở cấp thực thể sẽ ảnh hưởng đến các mối quan hệ (không giống như @Where
).