Hibernate HQL-запрос с функцией type () переставляет скобки - PullRequest
0 голосов
/ 01 февраля 2020

Я использую Spring Boot 2.1, Hibernate 5.2.10, и у меня возникает странная проблема в запросе HQL, определенном в репозитории Spring.

@Query(value = "SELECT m FROM Movement m LEFT JOIN FETCH m.wallet w LEFT JOIN FETCH w.contact c LEFT JOIN FETCH c.account acc JOIN FETCH m.checkPoint ck JOIN FETCH m.paymentType paymentType WHERE ((type(m)='MovementTicketBundle') OR (type(m)='MovementTicket') OR (type(m)='MovementRefund') OR ((type(m)='Movement') AND (m.wallet IS NULL)) )

Я использую функцию type () потому что Movement имеет несколько подклассов

@Inheritance(strategy = InheritanceType.SINGLE_TABLE
@DiscriminatorColumn(name = "type")
 public class Movement extends AbstractEntity {

Запрос, который задает Hibernate:

Hibernate: select movement0_.`id` as id2_28_0_, wallet1_.`id` as id1_56_1_, contact2_.`id` as id1_9_2_, account3_.`id` as id1_0_3_, checkpoint4_.`id` as id1_6_4_, paymenttyp5_.`id` as id1_30_5_, movement0_.`createdBy` as createdB3_28_0_, movement0_.`createdDate` as createdD4_28_0_, movement0_.`lastModifiedBy` as lastModi5_28_0_, movement0_.`lastModifiedDate` as lastModi6_28_0_, movement0_.`sid` as sid7_28_0_, movement0_.`version` as version8_28_0_, movement0_.`amount` as amount9_28_0_, movement0_.`checkPoint_id` as checkPo13_28_0_, movement0_.`currencyDate` as currenc10_28_0_, movement0_.`description` as descrip11_28_0_, movement0_.`details` as details12_28_0_, movement0_.`paymentType_id` as payment14_28_0_, movement0_.`wallet_id` as wallet_15_28_0_, movement0_.`ticketBundle_id` as ticketB16_28_0_, movement0_.`refund_id` as refund_17_28_0_, movement0_.`ticket_id` as ticket_18_28_0_, movement0_.`type` as type1_28_0_, wallet1_.`createdBy` as createdB2_56_1_, wallet1_.`createdDate` as createdD3_56_1_, wallet1_.`lastModifiedBy` as lastModi4_56_1_, wallet1_.`lastModifiedDate` as lastModi5_56_1_, wallet1_.`sid` as sid6_56_1_, wallet1_.`version` as version7_56_1_, wallet1_.`balance` as balance8_56_1_, wallet1_.`balanceNotified` as balanceN9_56_1_, wallet1_.`balanceThreshold` as balance10_56_1_, wallet1_.`contact_id` as contact11_56_1_, contact2_.`createdBy` as createdB2_9_2_, contact2_.`createdDate` as createdD3_9_2_, contact2_.`lastModifiedBy` as lastModi4_9_2_, contact2_.`lastModifiedDate` as lastModi5_9_2_, contact2_.`sid` as sid6_9_2_, contact2_.`version` as version7_9_2_, contact2_.`account_id` as account25_9_2_, contact2_.`address` as address8_9_2_, contact2_.`city` as city9_9_2_, contact2_.`country` as country10_9_2_, contact2_.`duplicated` as duplica11_9_2_, contact2_.`emails` as emails12_9_2_, contact2_.`enabled` as enabled13_9_2_, contact2_.`fax` as fax14_9_2_, contact2_.`iban` as iban15_9_2_, contact2_.`landlinePhone` as landlin16_9_2_, contact2_.`mobilePhone` as mobileP17_9_2_, contact2_.`name` as name18_9_2_, contact2_.`pec` as pec19_9_2_, contact2_.`personType` as personT20_9_2_, contact2_.`sdiAccountId` as sdiAcco21_9_2_, contact2_.`swift` as swift22_9_2_, contact2_.`taxCode` as taxCode23_9_2_, contact2_.`vatNumber` as vatNumb24_9_2_, account3_.`createdBy` as createdB2_0_3_, account3_.`createdDate` as createdD3_0_3_, account3_.`lastModifiedBy` as lastModi4_0_3_, account3_.`lastModifiedDate` as lastModi5_0_3_, account3_.`sid` as sid6_0_3_, account3_.`version` as version7_0_3_, account3_.`enabled` as enabled8_0_3_, account3_.`lastPasswordUpdate` as lastPass9_0_3_, account3_.`password` as passwor10_0_3_, account3_.`roles` as roles11_0_3_, account3_.`type` as type12_0_3_, account3_.`username` as usernam13_0_3_, checkpoint4_.`createdBy` as createdB2_6_4_, checkpoint4_.`createdDate` as createdD3_6_4_, checkpoint4_.`lastModifiedBy` as lastModi4_6_4_, checkpoint4_.`lastModifiedDate` as lastModi5_6_4_, checkpoint4_.`sid` as sid6_6_4_, checkpoint4_.`version` as version7_6_4_, checkpoint4_.`closingTime` as closingT8_6_4_, checkpoint4_.`code` as code9_6_4_, checkpoint4_.`fiscalPrinterSerialNumber` as fiscalP10_6_4_, checkpoint4_.`name` as name11_6_4_, checkpoint4_.`openingTime` as opening12_6_4_, checkpoint4_.`stockThreshold` as stockTh13_6_4_, checkpoint4_.`type` as type14_6_4_, (SELECT COUNT(*) FROM TicketBlock t WHERE t.CheckPoint_id=checkpoint4_.id) as formula2_4_, (SELECT COALESCE(SUM(t.lastTicketNumber-t.nextTicketNumber+1),0) FROM TicketBlock t WHERE t.CheckPoint_id=checkpoint4_.id) as formula3_4_, paymenttyp5_.`createdBy` as createdB2_30_5_, paymenttyp5_.`createdDate` as createdD3_30_5_, paymenttyp5_.`lastModifiedBy` as lastModi4_30_5_, paymenttyp5_.`lastModifiedDate` as lastModi5_30_5_, paymenttyp5_.`sid` as sid6_30_5_, paymenttyp5_.`version` as version7_30_5_, paymenttyp5_.`code` as code8_30_5_, paymenttyp5_.`ecommerceEnabled` as ecommerc9_30_5_, paymenttyp5_.`editable` as editabl10_30_5_, paymenttyp5_.`genre` as genre11_30_5_, paymenttyp5_.`icon` as icon12_30_5_, paymenttyp5_.`name` as name13_30_5_, paymenttyp5_.`sorting` as sorting14_30_5_ from `Movement` movement0_ left outer join `Wallet` wallet1_ on movement0_.`wallet_id`=wallet1_.`id` left outer join `Contact` contact2_ on wallet1_.`contact_id`=contact2_.`id` left outer join `Account` account3_ on contact2_.`account_id`=account3_.`id` inner join `CheckPoint` checkpoint4_ on movement0_.`checkPoint_id`=checkpoint4_.`id` inner join `PaymentType` paymenttyp5_ on movement0_.`paymentType_id`=paymenttyp5_.`id` where (movement0_.`type`='MovementTicketBundle' or movement0_.`type`='MovementTicket' or movement0_.`type`='MovementRefund' or movement0_.`type`='Movement' and (movement0_.`wallet_id` is null))

Все хорошо, но все в порядке, фактически эта часть неверна:

where (movement0_.`type`='MovementTicketBundle' or movement0_.`type`='MovementTicket' or movement0_.`type`='MovementRefund' or movement0_.`type`='Movement' and (movement0_.`wallet_id` is null))

Он удаляет скобки из условия Movement and wallet is null, я хочу, чтобы все это условие было помещено в ИЛИ с другими. Вместо этого квадратные скобки оставлены около (movement0_. wallet_id is null).

Я пытался перемещать браслеты несколькими способами, но результат тот же, поэтому я предполагаю, что Hibernate переписывает запрос так, как считает правильным.

Я что-то не так делаю, или это ошибка Hibernate? Любой намек или обходной путь?

...