[hibernate-dev] Possible regression on master
Vlad Mihalcea
mihalcea.vlad at gmail.com
Tue May 17 09:09:27 EDT 2016
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 <andrea at 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.vlad at 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 at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>
>
>
More information about the hibernate-dev
mailing list