2016-07-23 13 views
3

ich aus der Tabelle auf den Betrieb der Abfrage derselben Tabelle .JPA löschen müssen, istaus der Tabelle löschen, um auf gleiche wählen selben Tisch MariaDB JPA mit

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

ich diesen Fehler habe:

with root cause org.hibernate.hql.ast.QuerySyntaxException: unexpected token: (near line 1, column 109 [DELETE FROM com.bcits.bfm.model.ElectricityLedgerEntity a Where a.elLedgerid IN ( SELECT P.elLedgerid FROM (SELECT MAX(b.elLedgerid) FROM com.bcits.ElectricityLedgerEntity b WHERE b.accountId='24' and b.ledgerType='Electricity Ledger' and b.postType='ARREARS') P) ] at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54) at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47) at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:82) at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:284)

Gleiche Abfrage ist läuft auf mysql-terminal, aber das funktioniert nicht mit jpa. Kann mir jemand sagen, wie ich diese abfrage mit jpa schreiben kann.

+0

es sagt Ihnen, wo das Problem ... Spalte (Zeichen) 109 in dieser Abfrage ist. Vergleichen Sie es mit der JPQL-Spezifikation und Sie haben Ihre Antwort –

+0

Möchten Sie 'ElectricityLedgerEntity' mit max ID löschen? – ujulu

+0

@ujulu Ja, ich möchte ElectricityLedgerEntity mit max ID löschen. –

Antwort

0

Ich verstehe nicht, warum Sie P vor der letzten Klammer ...

Der folgende Code verwenden Sie ist nicht genug?

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

bearbeiten zur Umgehung mysql subquery Einschränkungen:

Der neue Fehler java.sql.SQLException: You can't specify target table 'LEDGER' for update in FROM clause ist in mysql bekannt, wenn Sie es mit JPA verwenden. Es ist eine MySQL-Einschränkung. A recent stackoverflow question about it
Kurz gesagt, man kann nicht „direkt“ aktualisiert/gelöscht eine Tabelle, die Sie in einer select Klausel Abfrage

Jetzt verstehe ich, warum Ihre ursprüngliche Abfrage mehrere Unterabfragen haben scheinbar nicht erforderlich (während es nützlich für mysql war) und hatte eine "spezielle" Syntax. Ich kenne keine Tricks, um dieses Problem in JPA zu lösen (ich benutze das MySQL DBMS seit langem nicht mehr).

Bei Ihnen würde ich zwei Abfragen durchführen. Das erste, wo Sie die erwartete maximale ElLedgerid auswählen und das zweite, wo Sie Zeile (n) mit der ID löschen konnten, die in der vorherigen Abfrage abgerufen wurde. Sie sollten keine Leistungsprobleme haben, wenn Ihr SQL-Modell gut gestaltet ist, die SQL-Indizes gut platziert sind und die Zeit für den Zugriff auf die Datenbank korrekt ist.

+0

das funktioniert nicht für mich, kannst du mir vorschlagen, wie ich das tun kann –

+0

@ anuj dhiman Ich habe die Abfrage bearbeitet, um eine einzige Unterabfrage zu haben. Laut den Logbüchern können Klammern der Schuldige sein. Ich glaube nicht, dass die Unterabfrage benötigt wurde. Kannst du testen und gib mir den Fehler. – davidxxx

+0

aktualisiert qeury zeigen Sie mir Fehler: java.sql.SQLException: Sie können Zieltabelle 'LEDGER' für das Update in FROM-Klausel –

0

Sie können dies nicht in einer einzelnen Abfrage mit Hibernate tun. Wenn Sie die maximale Zeile mit Hibernate löschen möchten, müssen Sie dies in zwei Schritten tun. Zuerst können Sie den maximalen Eintrag finden, dann können Sie diesen Wert in der WHERE-Klausel löschen.

Aber die Abfrage, die Sie geschrieben haben sollte tatsächlich als eine rohe MySQL-Abfrage ausgeführt werden. Warum versuchen Sie nicht, diese Abfrage als eine rohe Abfrage auszuführen:

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"); 
+0

interessante Sicht :) nicht angeben – davidxxx