2013-05-12 4 views
7

私はgrailsプロジェクトに取り組んでいます。私は実行しようとしている次のクエリを持っていますexecuteUpdateでHQLが不完全な 'クロス結合'を生成しています

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のリストへの参照がありません。

実行時に次の例外が発生します。

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 

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

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; 

おかげ

+0

両方のテーブルに 'CREATE'ステートメントを追加できますか? –

+0

@Declan_Kが作成スクリプトを追加しました – Amit

+0

私はついにNative SQLを使いました。ネイティブSQLの懸念は、ここで解決された新しいトランザクションを開始したくないということでした。http://stackoverflow.com/q/16507369/593644 – Amit

答えて

10

Hibernate documentation氏は述べていない:

んが、暗黙的または明示的、参加します、バルクHQLクエリで指定することができます。サブクエリにはwhere句を使用できます。where句では、サブクエリ自体にジョインが含まれる場合があります。

は、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クエリを使用する必要があります。

+0

私はこれを試してみます。しかし、私はMySQLが選択後にテーブルの 'UPDATE'を許可しないことを覚えています。 – Amit

+1

MySQLで動作しませんでした 'SQLException:FROM句で更新のためのターゲットテーブル 'location_trade'を指定することはできません。 – Amit

+1

次にSQLを使用する必要があります。 –

関連する問題