Jakob He created OPENJPA-2611:
---------------------------------
Summary: Bulk operations behave inconsistently to JPA Spec and
OpenJPA documentation
Key: OPENJPA-2611
URL: https://issues.apache.org/jira/browse/OPENJPA-2611
Project: OpenJPA
Issue Type: Bug
Components: jdbc
Affects Versions: 2.1.1
Environment: OpenJPA 2.1.1 in Websphere 8.0.0.10 on IBM J9 VM 2.6
Reporter: Jakob He
During mass data tests we discovered an undocumented behaviour in OpenJPA when
executing bulk operations via JPQL. OpenJPA decides to execute the bulk
operation completely in-memory if it detects either a CascadeType.REMOVE
annotation or a mapping to a different table on a field (1). The
in-memory-delete loads all entities which should be deleted into memory at
first and then deletes them manually to make sure no constraints are violated.
According to comments inside the OpenJPA source code it is clearly stated that
bulk deletes won't be performed with server-side operations if a mapping lies
in multiple tables (2).
Although this behaviour might be seen as a feature of OpenJPA, it is actually a
bug in either your documentation or your implementation regarding the JPA
specification. The official OpenJPA documentation says that "a (bulk) delete
operation only applies to entities of the specified class and its subclasses.
It does not cascade to related entities." (3) - however, the actual
implementation *will* cascade on a CascadeType.REMOVE annotation or a
orphanRemoval=true property (that's why OpenJPA performs the in-memory delete).
The JPA 2.0 specification contains exactly the same definition as your
documentation.
We stumbled upon this behaviour while investigating an OutOfMemoryError that
occurred during a load test in which OpenJPA should delete 1.4 million records
from our database. Although we discovered this bug in version 2.1.1 of OpenJPA,
a short look on GrepCode shows that the relevant source has been present at
least since 1.x and is still present in 2.4.0. It would be desireable if this
behaviour is at least documented outside of the source code, since users of
Hibernate or EclipseLink would not expect in-memory operations and might
experience OutOfMemoryErrors like we did. Otherwise it would be even better if
OpenJPA runs always a server-side bulk operation to conform with the JPA
specification or provide at least a documented configuration option for
disabling the in-memory operations. However, this would also mean, that
existing users who rely on the current implementation might get problems with
server-side constraints in the future.
If you know any way of disabling this behaviour without updating the OpenJPA
library, please let me know. The only workaround we currently see, is using
native SQL queries for bulk deleting records.
Sources:
(1):
http://grepcode.com/file/repo1.maven.org/maven2/org.apache.openjpa/openjpa-jdbc/2.4.0/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java#JDBCStoreQuery.getTable%28org.apache.openjpa.jdbc.meta.FieldMapping%2Corg.apache.openjpa.jdbc.schema.Table%29
(2):
http://grepcode.com/file/repo1.maven.org/maven2/org.apache.openjpa/openjpa-jdbc/2.1.1/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java#JDBCStoreQuery.isSingleTableMapping%28org.apache.openjpa.jdbc.meta.ClassMapping%2Cboolean%29
(3):
http://openjpa.apache.org/builds/2.4.0/apache-openjpa/docs/jpa_langref.html#jpa_langref_bulk_ops
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)