OpenJPA/MySQL:在 where 子句中使用同一张表时修改表

Posted

技术标签:

【中文标题】OpenJPA/MySQL:在 where 子句中使用同一张表时修改表【英文标题】:OpenJPA/MySQL: modifying a table while the same table is used in the where clause 【发布时间】:2017-08-08 06:13:21 【问题描述】:

我想通过 openJPA 和 mysql 执行删除查询。

这个 mysql 语句工作正常:

delete from GENERIC 
 where PARENT_ID not in (select g2.ID from (select * from GENERIC) g2);

基本元素是带有列 ID 和 PARENT_ID 的表 GENERIC

将 GENERIC 表映射到 GenericEntity 类,将 ID 列映射到(该类的)id 成员,将 PARENT_ID 列映射到 parentId 成员,我尝试了这个简单的测试:

entityManager.createQuery("delete from GenericEntity g1 where " +
   "g1.parentId not in " +
   "(select g2.id from (select * from GenericEntity) g2)"
).executeUpdate();

我得到这个错误:

org.apache.openjpa.persistence.ArgumentException:“遇到”g1。 parentId 不在 ( select g2 . id from (" at character 36, but 预期:[“(”,“*”,“+”,“,”,“-”,“。”,“/”,“:”,“”, “=”、“>”、“>=”、“?”、“ABS”、“ALL”、“AND”、“ANY”、“AS”、“ASC”、“AVG”、 “BETWEEN”、“BOTH”、“BY”、“CASE”、“CLASS”、“COALESCE”、“CONCAT”、 “COUNT”、“CURRENT_DATE”、“CURRENT_TIME”、“CURRENT_TIMESTAMP”、 “DELETE”、“DESC”、“DISTINCT”、“ELSE”、“EMPTY”、“END”、“ENTRY”、 “ESCAPE”、“EXISTS”、“FETCH”、“FROM”、“GROUP”、“HAVING”、“IN”、“INDEX”、 “INNER”、“IS”、“JOIN”、“KEY”、“LEADING”、“LEFT”、“LENGTH”、“LIKE”、 “LOCATE”、“LOWER”、“MAX”、“MEMBER”、“MIN”、“MOD”、“NEW”、“NOT”、 “NULL”、“NULLIF”、“OBJECT”、“OF”、“OR”、“ORDER”、“OUTER”、“SELECT”、 “SET”、“SIZE”、“SOME”、“SQRT”、“SUBSTRING”、“SUM”、“THEN”、“TRAILING”、 “TRIM”、“TYPE”、“UPDATE”、“UPPER”、“VALUE”、“WHEN”、“WHERE”、 , , , , , , , , ]." 在解析 JPQL 时"删除 GenericEntity g1 where g1.parentId not in (select g2.id from (select * 来自 GenericEntity) g2)"。查看原始解析的嵌套堆栈跟踪 错误。

我尝试了不同的变体,也将删除替换为更新(改为设置“已删除”标志),但是当在 where 子句中使用该表时,修改表似乎是一个普遍的问题。

非常感谢您提供提示、如何继续或指向任何有用材料的链接。 非常感谢您!

【问题讨论】:

错误信息来自jpql,不是来自mysql,所以我重新标记了这个问题。 【参考方案1】:

经过大量研究,我找到了解决方案。将选择与删除查询分开并将ID列表作为参数传递给删除语句可以正常工作:

List<Integer> idList = entityManager
    .createQuery("select g.id from GenericEntity g",Integer.class)
    .getResultList();
entityManager
    .createQuery("delete from GenericEntity g where g.parentId not in (:idList)")
    .setParameter("idList", idList)
    .executeUpdate();

【讨论】:

以上是关于OpenJPA/MySQL:在 where 子句中使用同一张表时修改表的主要内容,如果未能解决你的问题,请参考以下文章

为啥聚集函数不能出现在where子句中

在 from 子句 *and* where 子句中添加连接条件使查询更快。为啥?

如何在 EXECUTE IMMEDIATE 中使用动态 where 子句

5.WHERE 子句

在 from 子句或 where 子句中进行 equi join 是不是更好

不使用`where`子句,但得到错误:“未知列 在where子句中“