当前位置: 首页 > 面试题库 >

HQL在executeUpdate上生成不完整的“交叉连接”

汪驰
2023-03-14
问题内容

我正在做一个grails项目。我正在尝试执行以下查询

String CHECK_FOR_HIGH_TRADE_VOLUME_QUERY = "Update LocationTrade lt set lt.hasVeryHighVolume=true where lt.locationIndices=? AND lt.trade.volume>20000";

...

LocationTrade.executeUpdate(CHECK_FOR_HIGH_TRADE_VOLUME_QUERY, [indices]);

LocationTrade与Trade之间的关系是单向多对一的。因此,LocationTrade引用了Trade,但是Trade类没有引用LocationTrade列表。

执行时,出现以下异常。

org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute update query; SQL [update location_trade cross join  set has_very_high_volume=1 where location_indices_id=? and volume>20000]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute update query

and

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'set has_very_high_volume=1 where location_indices_id=997 and volume>20000' at line 1

似乎生成的查询是错误的。应该有一个与贸易表的联接,但这是缺失的。我无法识别我在这里犯的错误。有人可以帮我吗?

这两个表的创建脚本(我去除了一些无用的列)

CREATE TABLE `location_trade` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `version` bigint(20) NOT NULL,
  `auto_status` varchar(255) DEFAULT NULL,
  `exclusion_reason_description` varchar(255) DEFAULT NULL,
  `exclusion_reason_id` bigint(20) DEFAULT NULL,
  `exclusion_reason_title` varchar(255) DEFAULT NULL,
  `location_indices_id` bigint(20) DEFAULT NULL,
  `manual_status` varchar(255) DEFAULT NULL,
  `trade_id` bigint(20) DEFAULT NULL,
  `absolute_price` decimal(19,6) DEFAULT NULL,
  `flag` varchar(255) DEFAULT NULL,
  `auto_exclusion_reason` varchar(255) DEFAULT NULL,
  `date_created` datetime DEFAULT NULL,
  `exclusion_reason_text` varchar(255) DEFAULT NULL,
  `last_updated` datetime DEFAULT NULL,
  `has_very_high_volume` bit(1) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK858985A90CAA966` (`location_indices_id`),
  KEY `FK858985AB5FA6A69` (`trade_id`),
  CONSTRAINT `FK858985A90CAA966` FOREIGN KEY (`location_indices_id`) REFERENCES `location_indices` (`id`),
  CONSTRAINT `FK858985AB5FA6A69` FOREIGN KEY (`trade_id`) REFERENCES `trade` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25405 DEFAULT CHARSET=latin1;




CREATE TABLE `trade` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `version` bigint(20) NOT NULL,
  `comments` varchar(1020) DEFAULT NULL,
  `end_date` datetime DEFAULT NULL,
  `price` decimal(19,6) DEFAULT NULL,
  `price_type` varchar(255) DEFAULT NULL,
  `source_id` bigint(20) DEFAULT NULL,
  `start_date` datetime DEFAULT NULL,
  `trade_date` datetime DEFAULT NULL,
  `trade_name` varchar(255) DEFAULT NULL,
  `volume` decimal(19,6) DEFAULT NULL,
  `volume_units` varchar(255) DEFAULT NULL,
  `date_created` datetime DEFAULT NULL,
  `last_updated` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK697F1642D085935` (`source_id`),
  CONSTRAINT `FK697F1642D085935` FOREIGN KEY (`source_id`) REFERENCES `job_source` (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=26567 DEFAULT CHARSET=latin1;

谢谢


问题答案:

在Hibernate文档说:

批量HQL查询中不能指定隐式或显式连接。子查询可以在where子句中使用,其中子查询本身可能包含联接。

lt.trade.volume是LocationTrade和Trade之间的隐式内部联接,因此该查询无效。您必须将其重写为以下内容:

update LocationTrade lt set lt.hasVeryHighVolume=true where lt.locationIndices=? 
and lt.id in (
    select lt2.id from LocationTrade lt2 where lt2.trade.volume > 20000)

否则,您将不得不使用SQL查询。



 类似资料:
  • 我希望为结果提供内容过滤。我的(为简洁起见而编辑)实体如下所示: 节点: 场景: 来源: 下面是我希望实现的筛选器的一个示例。 给定一个SourceTypes集合,我希望选择所有场景,这样每个场景都会被其中一个类型的源引用。我使用QueryDSL和以下谓词实现了这一点: 一系列这些谓词被组合起来给出一个整体查询。即使只选择一个SourceType,结果查询看起来也是这样: 我相信上面发生的是交叉连

  • 问题内容: 我正在使用Hibernate 3.6和MSSQL 2012。 执行此HQL时 我正在获取此SQL 请注意 交叉连接 和where子句中的 附加条件* 。 根据Hibernate docs https://docs.jboss.org/hibernate/core/3.5/reference/en/html/queryhql.html#queryhql- joins- forms 隐式连

  • 根据Hibernate文档https://docs.jboss.org/Hibernate/core/3.5/referen/html/queryhql.html#queryhql-joins-forms 隐式联接应生成为内部联接。 我注意到有一个打开的bug https://hibernate.atlassian.net/browse/hhh-7707可能提到了这个问题,但没有人回答,而且它已经

  • 主要内容:笛卡尔积前面所讲的查询语句都是针对一个表的,但是在关系型数据库中,表与表之间是有联系的,所以在实际应用中,经常使用多表查询。多表查询就是同时查询两个或两个以上的表。 在 MySQL 中,多表查询主要有交叉连接、内连接和外连接。由于篇幅有限,本节主要讲解交叉连接查询。内连接和外连接将在《 MySQL内连接》和《 MySQL外连接》中讲解。 交叉连接(CROSS JOIN)一般用来返回连接表的笛卡尔积。 本节

  • 问题内容: 我正在尝试从表中的每个元素中提取所有对对,而该表是同一张表中的每个元素,这是我的查询: 我处于只需要一半记录的情况。我的天真尝试是: 但我无法在插入时查询目标表,如SQL Server所述: 我怎样才能有效地做到呢? 编辑 仅供参考,我说:“我需要一半的记录”,这是错误的,在服用后账户记录计数是 问题答案: 因此,只需对连接进行条件调整,以使左侧始终等于或小于左侧!

  • 我将PostgreSQL 9.6与Hibernate 5.2.10一起使用,并且有3个实体: 当Entity1加入Entity2通过Entity3过滤时,我需要删除Entity1的所有出现,如下所示: PS:在数据库中,所有的表都有外键。