JPA: Eclipselink not respecting em.remove()
eclipselink, ejb, glassfish, jpa
Solution
The reason could be that Eclipselink changes the order of operations during commit as stated in the Eclipselink documentation:
By default, EclipseLink does insert and update operations first, before delete operations, to ensure that referential integrity is maintained. This is the preferred approach.
You can change this behavior either by flushing (as you already found out) or by setting a special parameter for Eclipselink:
If you are forced to replace an object with unique constraints by deleting it and inserting a replacement, you may cause a constraint violation if the insert operation occurs before the delete operation. In this case, call `setShouldPerformDeletesFirst` to perform the delete operation before the insert operation.
Problem
I need to delete one entity and create another: ``` @Stateless public class StatelessBean { @PersistenceUnit(unitName = "Unit001") EntityManagerFactory emf; protected void test() { EntityManager em = emf.createEntityManager(); MyObj obj1 = em.find(MyObj.class, 100); MyObj obj2 = new MyObj(); obj2.setKey("the same unique key as in obj1"); em.remove(obj1); // em.flush(); em.persist(obj2); // works fine when flush() is uncommented em.close(); } } ``` If I leave `em.flush()` commented, then I get `com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException` (new and old objects have equal key value) What could be the reason for such an abnormal behavior? Server: Glassfish 3.1.2 Eclipse Persistence Services - 2.3.2.v20111125-r10461 persistence.xml: ``` <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="Unit001"> <jta-data-source>jdbc/Unit001DS</jta-data-source> <properties> <property name="eclipselink.logging.level" value="INFO"/> <property name="eclipselink.target-database" value="MySQL"/> </properties> </persistence-unit> </persistence> ``` Connection pool: ``` ${ASADMIN} --port ${DOMAIN_ADMIN_PORT} create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource --restype javax.sql.ConnectionPoolDataSource --property "User=user:Password=pass:URL=jdbc\:mysql\://${DB_ADDRESS}/db" Unit001DS ${ASADMIN} --port ${DOMAIN_ADMIN_PORT} create-jdbc-resource --connectionpoolid Unit001DS jdbc/Unit001DS ```