13

私は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 の関係は、一方向の多対 1 です。したがって、LocationTrade には Trade への参照がありますが、Trade クラスには LocationTrade の List への参照がありません。

実行すると、次の例外が発生します。

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

生成されたクエリが間違っているようです。Trade テーブルとの結合があるはずですが、それがありません。ここで行ったエラーを特定できません。何人か助けてくれませんか?

2 つのテーブルの作成スクリプト (重要でない列の一部を削除しました)

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;

ありがとう

4

1 に答える 1

16

Hibernate のドキュメントには次のように書かれています。

一括 HQL クエリでは、暗黙的または明示的な結合を指定できません。サブクエリは、サブクエリ自体に結合を含めることができる where 句で使用できます。

lt.trade.volumeLocationTrade と 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 クエリを使用する必要があります。

于 2013-05-12T11:50:46.380 に答える