You can workaround it by setting:

openjpa.jdbc.DBDictionary = mysql(supportsCorrelatedSubselect=false)

This will force openjpa to revert to in-memory bulk operation. Be warned that it'll be grossly inefficient for anything beyond a few rows, as openjpa will select the rows matching your where clause and then issue a separate delete statement for each row. The only alternative is to fallback to plain JDBC prepared statements.

That's actually a rather nasty issue, all bulk operations involving a where clause against mysql fail because of that. Since I'm writing a very performance-aware app myself, I've dug deep into fixing it but I can't find a sensible way to do it. DBDictionary.toBulkOperation() relies on the select statement passed to it to build the final bulk update/delete statement, and that select always has table aliases embedded to it, even if where clause spans a single table as in Ognjen's example.

If Patrick or any openjpa veteran can offer a strategy to fix it, I'll gladly put in the time to implement it.

Ognjen Blagojevic wrote:
I try to do an update by query like this

 em = emf.createEntityManager();
 em.getTransaction().begin();
 Query q = em.createQuery(
"UPDATE SifTipInstitucije o SET o.nazivEngleski='someText' WHERE o.idTipInstitucije = 1");
 int updated = q.executeUpdate();
 em.getTransaction().commit();
 em.close();

But it seems that OpenJPA (1.0.0) translates this into

UPDATE sif_tip_institucije
   SET naziv_engleski = ?
 WHERE id_tip_institucije IN
       (SELECT DISTINCT t0.id_tip_institucije
          FROM sif_tip_institucije t0
         WHERE (t0.id_tip_institucije = ?))

[params=(String) someText, (long) 1]

Which is not legal MySQL query... It throws the exception:

You can't specify target table 'sif_tip_institucije' for update in FROM clause.

Is this a bug? Should I log a JIRA?

Regards,
Ognjen

Reply via email to