简体   繁体   English

使用连接或嵌套子查询 Hibernate (HQL) 进行更新

[英]Update using join or nasted sub-query Hibernate (HQL)

I have a problem creating HQL that updates entity CommitteeMembership with nested queries or using joins, i tried this query first:我在创建使用嵌套查询或使用联接更新实体 CommitteeMembership 的 HQL 时遇到问题,我首先尝试了此查询:

update CommitteeMemberShip cms set cms.isDeleted=1 
where cms.committeeCycle.committee.id=:committeeId

but the generated SQL was wrong as following:但生成的 SQL 错误如下:

update CommitteeMemberShip cross join  set isDeleted=1 where committee_id=?

without any this after "cross join" makes Hibernate throws SQLGrammarException在“交叉连接”之后没有任何这个使得 Hibernate 抛出 SQLGrammarException

After that, i have changed my query to use sub-query:之后,我将查询更改为使用子查询:

update CommitteeMemberShip cms set cms.isDeleted=1 
where cms.id in (select cmsIn.id from CommitteeMemberShip cmsIn inner join 
cmsIn.committeeCycle cc inner join cc.committee c where c.id=:committeeId)

now Hibernate throws现在 Hibernate 抛出

java.sql.SQLException: You can't specify target table 'CommitteeMemberShip' for 
update in FROM clause

any one have any idea how i can write this update query in HQL??任何人都知道如何在 HQL 中编写此更新查询?

Try this 尝试这个

update CommitteeMemberShip cms set cms.isDeleted=1 where cms.id = some(select cmsIn.id from CommitteeMemberShip cmsIn inner join cmsIn.committeeCycle cc inner join cc.committee c where c.id=:committeeId) 更新CommitteeMemberShip cms设置cms.isDeleted = 1其中cms.id =一些

尝试使用此“ UPDATE table1 r SET r.column = @value WHERE r.column IN(“从r.table2 rd中选择rd.Id的地方rd.Column ='” + @ value +“'AND rd.Column ='” + value + “'”;

It seems that HQL does not yet support path expressions / implicit joins in DML statements. HQL 似乎还不支持 DML 语句中的路径表达式/隐式连接。 Here's how jOOQ does it (in SQL, assuming all paths are to-one relationships): 这是 jOOQ 的做法(在 SQL 中,假设所有路径都是一对一的关系):

UPDATE CommitteeMemberShip cms
SET cms.isDeleted = 1
WHERE (
  SELECT Committee.id
  FROM Committee
  WHERE (
    SELECT CommitteeCycle.committeeId
    FROM CommitteeCycle
    WHERE CommitteeCycle.id = cms.committeeCycleId
  ) = Committee.id 
) = :committeeId

Your own approach didn't work because you repeated the CommitteeMemberShip entity unnecessarily.您自己的方法不起作用,因为您不必要地重复了CommitteeMemberShip实体。 That's a known MySQL limitation, see: MySQL Error 1093 - Can't specify target table for update in FROM clause这是已知的 MySQL 限制,请参阅: MySQL 错误 1093 - 无法在 FROM 子句中指定要更新的目标表

This would have worked, I suspect?我怀疑这会奏效吗?

UPDATE CommitteeMemberShip cms
SET cms.isDeleted = 1
WHERE cms.committeeCycleId IN (
  SELECT CommitteeCycle.id
  FROM CommitteeCycle cc
  JOIN cc.committee c
  WHERE c.id = :committeeId
)

Starting with Hibernate 6 and their support for derived tables, you might be able to work around MySQL's limitation like this ( the same way as jOOQ does it out of the box, see here ):从 Hibernate 6 及其对派生表的支持开始,您可能可以像这样解决 MySQL 的限制(与 jOOQ 开箱即用的方式相同,请参见此处):

UPDATE CommitteeMemberShip cms 
SET cms.isDeleted=1 
WHERE cms.id IN (
  -- Wrap the query once more in a derived table
  SELECT t.id
  FROM (
    SELECT cmsIn.id 
    FROM CommitteeMemberShip cmsIn 
    JOIN cmsIn.committeeCycle cc 
    JOIN cc.committee c WHERE c.id=:committeeId
  ) t
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM