使用jpa

时间:2016-07-23 05:38:52

标签: java mysql hibernate jpa mariadb

我需要从表中删除同一表.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编写此查询。

3 个答案:

答案 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开始解除了这个问题:

  

Same Source and Target Table

     

在MariaDB 10.3.1之前,无法从具有相同源和目标的表中删除。从MariaDB 10.3.1开始,现在可以实现。例如:

DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);