[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-7252) EntityManager not retaining LockOptions context when mapping exceptions.

Bryan Varner (JIRA) noreply at atlassian.com
Fri Apr 20 10:12:48 EDT 2012


    [ https://hibernate.onjira.com/browse/HHH-7252?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=46362#comment-46362 ] 

Bryan Varner commented on HHH-7252:
-----------------------------------

New pull request with test case. This is potentially going to expose the same problem I had with PostgreSQL in HHH-7251 for other dialects.

I do not have the means to run the matrix tests for all dialects. sebersol has told me to make the pull request in IRC, so here it is.

https://github.com/hibernate/hibernate-orm/pull/317



> EntityManager not retaining LockOptions context when mapping exceptions.
> ------------------------------------------------------------------------
>
>                 Key: HHH-7252
>                 URL: https://hibernate.onjira.com/browse/HHH-7252
>             Project: Hibernate ORM
>          Issue Type: Bug
>          Components: entity-manager
>    Affects Versions: 4.1.2
>         Environment: PostgreSQL 9.1
>            Reporter: Bryan Varner
>            Priority: Critical
>   Original Estimate: 5m
>  Remaining Estimate: 5m
>
> AbstractEntityManagerImpl.java:791 (Implementation of EntityManager.find())
> This line defines a local LockOptions and sets it to null.
> A conditional execution for including lock options on line 795 evaluates the LockOptions but never sets it back to the local.
> When an exception occurs (lock timeout, or otherwise) the lockOptions have not been set to anything but null, and incorrect exceptions are resolved and thrown.
> Specifically, you get PessimisticLockException even when you should get LockTimeoutException.
> This is marking transactions as rollback only, and causing subsequent code to fail gloriously.
> Below is the offensive function, notice that lockOptions is never set to anything other than =null.
> {code}
> 	public <A> A find(Class<A> entityClass, Object primaryKey, LockModeType lockModeType, Map<String, Object> properties) {
> 		CacheMode previousCacheMode = getSession().getCacheMode();
> 		CacheMode cacheMode = determineAppropriateLocalCacheMode( properties );
> 		LockOptions lockOptions = null;
> 		try {
> 			getSession().setCacheMode( cacheMode );
> 			if ( lockModeType != null ) {
> 				return ( A ) getSession().get(
> 						entityClass, ( Serializable ) primaryKey,
> 						getLockRequest( lockModeType, properties )
> 				);
> 			}
> 			else {
> 				return ( A ) getSession().get( entityClass, ( Serializable ) primaryKey );
> 			}
> 		}
> 		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 e ) {
> 			throw new IllegalArgumentException( e.getMessage(), e );
> 		}
> 		catch ( TypeMismatchException e ) {
> 			throw new IllegalArgumentException( e.getMessage(), e );
> 		}
> 		catch ( ClassCastException e ) {
> 			throw new IllegalArgumentException( e.getMessage(), e );
> 		}
> 		catch ( HibernateException he ) {
> 			throw convert( he, lockOptions );
> 		}
> 		finally {
> 			getSession().setCacheMode( previousCacheMode );
> 		}
> 	}
> {code}

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list