Saya mengaktifkan logging SQL dan memeriksa output kueri. Untuk kasus di atas begini:
/* 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=?
Jadi gabungan yang diperlukan sudah disertakan dan terlihat seperti yang dibutuhkan hanyalah ini:
@Where(clause = "ppg_status <> 'D'")
Namun, ternyata tidak bekerja sebagai Hibernate menambahkan alias tabel yang salah:
where
(
purchasepr0_.ppg_status <> 'D'
)
and purchasepr0_.crd_id=?
Sayangnya setelah alias ditetapkan ke tabel, nama tabel asli tidak dapat digunakan - jadi purchase_product_group.ppg_status <> 'D'
tidak akan berhasil. Dan saya tidak mengetahui cara untuk menentukan nama alias yang digunakan oleh Hibernate secara terprogram - jadi saat ini pilihannya tampaknya berupa hard-code nama alias yang ditemukan digunakan oleh Hibernate (yaitu purchasepr1_.ppg_status <> 'D'
) atau untuk menggunakan exists
metode yang dijelaskan dalam pertanyaan.
PERBARUI: Pada penyelidikan lebih lanjut ternyata hard-coding nama alias tidak selalu bisa diterapkan. Berikut adalah kueri kriteria yang tidak berfungsi:
/* 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=?
Pada akhirnya saya meninggalkan @Where
pendekatan dan gunakan @Filter
sebagai gantinya, yang tampaknya jauh lebih baik karena dapat menerima HQL daripada nama bidang basis data dan ketika diterapkan pada tingkat entitas akan memengaruhi hubungan (tidak seperti @Where
).