-
Bug
-
Resolution: Done
-
Major
-
None
added a check for roll-back-only condition, however, we should first check for active JTA transaction. The reason is that when Hibernate ORM calls accessTransaction().getRollbackOnly(), an ISE exception is immediately thrown by org.hibernate.engine.transaction.internal.TransactionImpl.getRollbackOnly, which is confusing to users, as they called EntityManager.find(), which shouldn't throw "IllegalStateException: JPA compliance dictates throwing IllegalStateException when #getRollbackOnly is called on non-active transaction", as the application didn't call #getRollbackOnly.
I suggest a change from:
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockModeType, Map<String, Object> properties) { checkOpen(); LockOptions lockOptions = null; try { getLoadQueryInfluencers().getEffectiveEntityGraph().applyConfiguredGraph( properties ); final IdentifierLoadAccess<T> loadAccess = byId( entityClass ); loadAccess.with( determineAppropriateLocalCacheMode( properties ) ); if ( lockModeType != null ) { if ( !LockModeType.NONE.equals( lockModeType) ) { checkTransactionNeededForUpdateOperation(); } lockOptions = buildLockOptions( lockModeType, properties ); loadAccess.with( lockOptions ); } return loadAccess.load( (Serializable) primaryKey ); } catch ( EntityNotFoundException ignored ) { // DefaultLoadEventListener.returnNarrowedProxy may throw ENFE (see HHH-7861 for details), // which find() should not throw. Find() should return null if the entity was not found. if ( log.isDebugEnabled() ) { String entityName = entityClass != null ? entityClass.getName(): null; String identifierValue = primaryKey != null ? primaryKey.toString() : null ; log.ignoringEntityNotFound( entityName, identifierValue ); } return null; } catch ( ObjectDeletedException e ) { //the spec is silent about people doing remove() find() on the same PC return null; } catch ( ObjectNotFoundException e ) { //should not happen on the entity itself with get throw new IllegalArgumentException( e.getMessage(), e ); } catch ( MappingException | TypeMismatchException | ClassCastException e ) { throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage(), e ) ); } catch ( JDBCException e ) { if ( accessTransaction().getRollbackOnly() ) { // assume this is the similar to the WildFly / IronJacamar "feature" described under HHH-12472 return null; } else { throw exceptionConverter.convert( e, lockOptions ); } } catch ( RuntimeException e ) { throw exceptionConverter.convert( e, lockOptions ); } finally { getLoadQueryInfluencers().getEffectiveEntityGraph().clear(); } }
Change instead to:
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockModeType, Map<String, Object> properties) { checkOpen(); LockOptions lockOptions = null; try { getLoadQueryInfluencers().getEffectiveEntityGraph().applyConfiguredGraph( properties ); final IdentifierLoadAccess<T> loadAccess = byId( entityClass ); loadAccess.with( determineAppropriateLocalCacheMode( properties ) ); if ( lockModeType != null ) { if ( !LockModeType.NONE.equals( lockModeType) ) { checkTransactionNeededForUpdateOperation(); } lockOptions = buildLockOptions( lockModeType, properties ); loadAccess.with( lockOptions ); } return loadAccess.load( (Serializable) primaryKey ); } catch ( EntityNotFoundException ignored ) { // DefaultLoadEventListener.returnNarrowedProxy may throw ENFE (see HHH-7861 for details), // which find() should not throw. Find() should return null if the entity was not found. if ( log.isDebugEnabled() ) { String entityName = entityClass != null ? entityClass.getName(): null; String identifierValue = primaryKey != null ? primaryKey.toString() : null ; log.ignoringEntityNotFound( entityName, identifierValue ); } return null; } catch ( ObjectDeletedException e ) { //the spec is silent about people doing remove() find() on the same PC return null; } catch ( ObjectNotFoundException e ) { //should not happen on the entity itself with get throw new IllegalArgumentException( e.getMessage(), e ); } catch ( MappingException | TypeMismatchException | ClassCastException e ) { throw exceptionConverter.convert( new IllegalArgumentException( e.getMessage(), e ) ); } catch ( JDBCException e ) { // Note one line change is below. if ( accessTransaction().isActive() && accessTransaction().getRollbackOnly() && accessTransaction().getRollbackOnly() ) { // assume this is the similar to the WildFly / IronJacamar "feature" described under HHH-12472 return null; } else { throw exceptionConverter.convert( e, lockOptions ); } } catch ( RuntimeException e ) { throw exceptionConverter.convert( e, lockOptions ); } finally { getLoadQueryInfluencers().getEffectiveEntityGraph().clear(); } }
I'll try the above change locally and check if the current ORM testsuite still passes (on ORM master branch).
- is incorporated by
-
JBEAP-17963 [GSS](7.2.z) Upgrade Hibernate ORM from 5.3.14.Final-redhat-00001 to 5.3.15.Final-redhat-00001
- Closed
- incorporates
-
HHH-13433 Loading...