Hi, While fixing tests for Oracle after rebasing my branch, I realized that the org.hibernate.test.optlock.OptimisticLockTest > testOptimisticLockAllDelete fails on Oracle10gDialect, while running just fine on H2.
When reaching the following branching logic in AbstractEntityPersister: if ( useBatch ) { session.getJdbcCoordinator().getBatch( deleteBatchKey ).addToBatch(); } else { check( session.getJdbcCoordinator().getResultSetReturn().executeUpdate( delete ), id, j, expectation, delete ); } If using H2, we go to the useBatch branch, while for Oracle dialects that are less than 12c (hibernate.jdbc.batch_versioned_data is set to false, therefore JDBC batching is disabled) it goes on the second branch logic. This way, for H2, a StaleStateException is thrown and the flush operation flow is disrupted. For Oracle, the check method call will throw a StaleObjectStateException instead: catch (StaleStateException e) { if ( !isNullableTable( tableNumber ) ) { if ( getFactory().getStatistics().isStatisticsEnabled() ) { getFactory().getStatisticsImplementor() .optimisticFailure( getEntityName() ); } throw new StaleObjectStateException( getEntityName(), id ); } return false; } Now, there is a difference between how the ExceptionConverterImpl handles StaleStateException and StaleObjectStateException because for the latter, it tries to fetch the entity in question: final Object entity = sharedSessionContract.load( sose.getEntityName(), identifier ); Because there is no proxy loaded in the current Session, the DefaultLoadEntityListener will execute the createProxyIfNecessary method, and because the entity was deleted, it will return null: EntityEntry entry = persistenceContext.getEntry( existing ); Status status = entry.getStatus(); if ( status == Status.DELETED || status == Status.GONE ) { return null; } However, getReference() throws an exception when there is no object being found: getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityPersister.getEntityName(), id ); So instead of a StaleObjectStateException, we get an ObjectNotFoundException. One quick fix is to just catch that ObjectNotFoundException: Object entity; try { entity = sharedSessionContract.load( sose.getEntityName(), identifier ); } catch(ObjectNotFoundException e) { entity = null; } if ( entity instanceof Serializable ) { //avoid some user errors regarding boundary crossing pe = new OptimisticLockException( e.getMessage(), e, entity ); } else { pe = new OptimisticLockException( e.getMessage(), e ); } Or maybe there is some other fix that you might think of. Vlad _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev