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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With