我需要从表中删除同一表.JPA查询的操作
DELETE FROM com.model.ElectricityLedgerEntity a
Where a.elLedgerid IN
(SELECT P.elLedgerid FROM
(SELECT MAX(b.elLedgerid)
FROM com.model.ElectricityLedgerEntity b
WHERE b.accountId='24' and b.ledgerType='Electricity Ledger' and b.postType='ARREARS') P );
我收到了这个错误:
有根本原因org.hibernate.hql.ast.QuerySyntaxException:意外 token :(靠近第1行,第109列[DELETE FROM com.bcits.bfm.model.ElectricityLedgerEntity a a.elLedgerid IN( SELECT P.elLedgerid FROM(SELECT MAX(b.elLedgerid)FROM com.bcits.ElectricityLedgerEntity b WHERE b.accountId = '24' 和b.ledgerType ='电力分类帐'和b.postType ='ARREARS')P)] 在 org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54) 在 org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47) 在 org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:82) 在 org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:284)
相同的查询在mysql终端上运行,但这不适用于jpa。可以告诉我如何使用jpa编写此查询。
答案 0 :(得分:0)
我不明白为什么在最后一个括号之前使用P
...
以下代码是不够的?
DELETE FROM com.model.ElectricityLedgerEntity a
Where a.elLedgerid IN
(SELECT MAX(b.elLedgerid)
FROM com.model.ElectricityLedgerEntity b
WHERE b.accountId='24' and b.ledgerType='Electricity Ledger' and
b.postType='ARREARS')
编辑以绕过mysql子查询限制:
新错误java.sql.SQLException: You can't specify target table 'LEDGER' for update in FROM clause
在JPA中使用时,它在mysql中是已知的。这是MySQL的一个限制。
A recent stackoverflow question about it
简而言之,您不能“直接”更新/删除您在select
子句
现在我理解为什么你的原始查询做了多个子查询似乎没有必要(虽然它对mysql有用)并且有一个“特殊”语法。 我不知道在JPA中解决这个问题的技巧(我现在很长时间没有使用MySQL DBMS)。
在你的地方,我会做两个问题。第一个是您选择预期的最大elLedgerid,第二个是您可以删除上一个查询中检索到的行的行。 如果您的sql模型设计得很好,sql索引放置得很好并且访问数据库的时间是正确的,那么您不应该遇到性能问题。
答案 1 :(得分:0)
您无法在使用Hibernate的单个查询中执行此操作。如果你想用Hibernate删除最大行,你必须分两步完成。首先,您可以找到最大条目,然后可以使用WHERE
子句中的该值删除。
但是您编写的的查询应该实际上作为原始MySQL查询运行。那么为什么不尝试将该查询作为原始查询执行:
String sql = "DELETE FROM com.model.ElectricityLedgerEntity a " +
"WHERE a.elLedgerid IN (SELECT P.elLedgerid FROM " +
"(SELECT MAX(b.elLedgerid) FROM com.model.ElectricityLedgerEntity b " +
"WHERE b.accountId = :account_id AND b.ledgerType = :ledger_type AND " +
" b.postType = :post_type) P );";
Query query = session.createSQLQuery(sql);
query.setParameter("account_id", "24");
query.setParameter("ledger_type", "Electricity Ledger");
query.setParameter("post_type", "ARREARS");
答案 2 :(得分:0)
只想扩展existing answer:
简而言之,您不能“直接”更新/删除您在select子句中查询的表
从MariaDB 10.3.1开始解除了这个问题:
在MariaDB 10.3.1之前,无法从具有相同源和目标的表中删除。从MariaDB 10.3.1开始,现在可以实现。例如:
DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);