首页 > 解决方案 > 带有 type() 函数的 Hibernate HQL 查询重新排列括号

问题描述

我正在使用 Spring Boot 2.1、Hibernate 5.2.10,并且在定义到 Spring 存储库中的 HQL 查询中遇到了一个奇怪的问题。

@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,我希望将整个条件与其他条件放在 OR 中。相反,括号留在(movement0_.wallet_id周围is null)

我试图以多种方式移动刹车,但结果是一样的,所以我的猜测是 Hibernate 重写了它认为正确的查询。

我做错了什么,还是 Hibernate 的错误?任何提示或解决方法?

标签: javaspringhibernatespring-data-jpa

解决方案


推荐阅读