简体   繁体   中英

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:

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

but the generated SQL was wrong as following:

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

without any this after "cross join" makes Hibernate throws 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

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??

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)

尝试使用此“ 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. Here's how jOOQ does it (in SQL, assuming all paths are to-one relationships):

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. That's a known MySQL limitation, see: MySQL Error 1093 - Can't specify target table for update in FROM clause

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 ):

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
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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