| Summary: | EntityManager Duplicate Inserts in 2.4 where 2.3.2 works well | ||
|---|---|---|---|
| Product: | z_Archived | Reporter: | Bernard Missing name <bht237> |
| Component: | Eclipselink | Assignee: | Project Inbox <eclipselink.orm-inbox> |
| Status: | CLOSED INVALID | QA Contact: | |
| Severity: | blocker | ||
| Priority: | P3 | ||
| Version: | unspecified | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
My tests contained code that was upsetting 2.4 but was tolerated by 2.3 and below. Found it using <property name="eclipselink.validate-existence" value="true"/> The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink |
Hundreds of JUnit tests fail in 2.4 that pass with 2.3 and below. It looks like database inserts are repeated within EntityManager, resulting in duplicate insert attempts. However application code cannot produce duplicates because entities have @GeneratedValue(strategy=GenerationType.TABLE, generator="MY_GENERATOR") @TableGenerator(name="MY_GENERATOR") I have tried for a whole day to make a test case but I was unable to. When I reduce the number of tests in the test class, then the problems disappear mysteriously. Perhaps this depends on load. I would need some tips and tricks to nail this down as a test case. For me this is a blocker because there is no way that I can deploy 2.4. The JUnit setup is as follows: private static EntityManagerFactory emf; private static EntityManager em; private static EntityTransaction trans; private static SomeService instance; @BeforeClass public static void setUpClass() throws Exception { emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); em = emf.createEntityManager(); instance = new SomeService(em); } @AfterClass public static void tearDownClass() throws Exception { em.close(); emf.close(); } @Before public void setUp() { trans = em.getTransaction(); trans.begin(); } @After public void tearDown() { // Flush to catch any database issues eg duplicate inserts em.flush(); trans.rollback(); } @Test public void testSomething() { Object result = instance.doSomething(); assertNotNull(result); } The errors are is like this: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "key_name" Detail: Key (id)=(751) already exists. Error Code: 0 Call: INSERT INTO ... VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) bind => [15 parameters bound] Query: InsertObjectQuery(entity.toString()) at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:804) at <class under test> Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "key_name" Detail: Key (id)=(751) already exists. Error Code: 0 Call: INSERT INTO <same as before> at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333) at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1501) at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:849) at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:913) at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:594) at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:537) at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1800) at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:286) at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207) at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193) at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:342) at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:162) at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:177) at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:471) at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80) at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90) at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:286) at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58) at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:852) at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:751) at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108) at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2875) at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1602) at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1584) at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1535) at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:224) at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:123) at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3914) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1419) at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:634) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithPreBuiltChangeSet(UnitOfWorkImpl.java:1565) at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:445) at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:798) Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "gee1offer_pkey" Detail: Key (id)=(751) already exists. at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257) at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334) at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:842)