Or we could add the: Object get(Class entityClass, Serializable id);
method to SharedSessionContract since both SessionImpl and StatelessSessionImpl implement it. This way we can call: entity = sharedSessionContract.get( sose.getEntityName(), identifier ); and leave the current check which verifies if entity is Serializable. Vlad On Tue, May 17, 2016 at 3:54 PM, andrea boriero <and...@hibernate.org> wrote: > what about adding a > catch(ObjectNotFoundException onfe){ > pe = new OptimisticLockException( e.getMessage, e); > } > to the existing try/catch that encloses the entity = > sharedSessionContract.load( sose.getEntityName(), identifier ) ? > > On 17 May 2016 at 13:32, Vlad Mihalcea <mihalcea.v...@gmail.com> wrote: > >> 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 >> > > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev