[hibernate-commits] Hibernate SVN: r18209 - in core/trunk: core/src/main/java/org/hibernate/exception and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Dec 11 08:23:17 EST 2009


Author: smarlow at redhat.com
Date: 2009-12-11 08:23:17 -0500 (Fri, 11 Dec 2009)
New Revision: 18209

Modified:
   core/trunk/core/src/main/java/org/hibernate/PessimisticLockException.java
   core/trunk/core/src/main/java/org/hibernate/exception/SQLStateConverter.java
   core/trunk/core/src/main/java/org/hibernate/loader/Loader.java
   core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/HibernateEntityManagerImplementor.java
Log:
HHH-4546 JPA-2.0 locking.  More pessimistic lock exception support and timeout exception support

Modified: core/trunk/core/src/main/java/org/hibernate/PessimisticLockException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/PessimisticLockException.java	2009-12-11 12:40:05 UTC (rev 18208)
+++ core/trunk/core/src/main/java/org/hibernate/PessimisticLockException.java	2009-12-11 13:23:17 UTC (rev 18209)
@@ -24,29 +24,33 @@
  */
 package org.hibernate;
 
+import java.sql.SQLException;
+
 /**
  *
- * Throw when an pessimistic locking conflict occurs.
+ * Thrown when a pessimistic locking conflict occurs.
  *
  * @author Scott Marlow
  */
-public class PessimisticLockException extends HibernateException {
+public class PessimisticLockException extends JDBCException {
 
 	Object entity;
 
-	public PessimisticLockException(String s) {
-		super(s);
-	}
 
-   public PessimisticLockException(String s, Throwable throwable, Object entity) {
-         super(s, throwable);
+	public PessimisticLockException(String s, JDBCException je, Object entity) {
+			super(s, je.getSQLException());
+			this.entity = entity;
+		}
+
+   public PessimisticLockException(String s, SQLException se, Object entity) {
+         super(s, se);
          this.entity = entity;
       }
 
-	public PessimisticLockException(String s, Object entity) {
-		super(s);
-		this.entity = entity;
-	}
+	public PessimisticLockException(String s, SQLException se, String sql) {
+			super(s, se, sql);
+			this.entity = null;
+		}
 
 	public Object getEntity() {
 		return entity;

Modified: core/trunk/core/src/main/java/org/hibernate/exception/SQLStateConverter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/SQLStateConverter.java	2009-12-11 12:40:05 UTC (rev 18208)
+++ core/trunk/core/src/main/java/org/hibernate/exception/SQLStateConverter.java	2009-12-11 13:23:17 UTC (rev 18209)
@@ -25,6 +25,7 @@
 package org.hibernate.exception;
 
 import org.hibernate.JDBCException;
+import org.hibernate.PessimisticLockException;
 
 import java.sql.SQLException;
 import java.util.HashSet;
@@ -109,6 +110,11 @@
 				// oracle sql-state code for deadlock
 				return new LockAcquisitionException( message, sqlException, sql );
 			}
+
+			if ( "40XL1".equals( sqlState ) || "40XL2".equals( sqlState )) {
+				// Derby "A lock could not be obtained within the time requested."
+				return new PessimisticLockException( message, sqlException, sql );
+			}
 		}
 
 		return handledNonSpecificException( sqlException, message, sql );

Modified: core/trunk/core/src/main/java/org/hibernate/loader/Loader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/Loader.java	2009-12-11 12:40:05 UTC (rev 18208)
+++ core/trunk/core/src/main/java/org/hibernate/loader/Loader.java	2009-12-11 13:23:17 UTC (rev 18209)
@@ -214,14 +214,35 @@
 		return null;
 	}
 
+	private Map buildLockMap(Map locks) {
+		Map result = locks;
+		if ( result == null ) {
+			LockOptions[] lockArray = getLockOptions(result);
+			String[] aliases = getAliases();
+			if (aliases != null &&
+				lockArray != null &&
+				lockArray.length > 0 &&
+				lockArray.length == aliases.length &&
+				lockArray[0].getLockMode() != LockMode.NONE ) {
+				result = new HashMap();
+				for ( int looper = 0; looper < lockArray.length; looper++ ) {
+					result.put(aliases[looper], lockArray[looper]);
+				}
+			}
+		}
+
+		return result;
+	}
 	/**
 	 * Modify the SQL, adding lock hints and comments, if necessary
 	 */
 	protected String preprocessSQL(String sql, QueryParameters parameters, Dialect dialect)
 			throws HibernateException {
+
+		Map locks = buildLockMap(parameters.getLockOptions());
+
+		sql = applyLocks( sql, locks, dialect );
 		
-		sql = applyLocks( sql, parameters.getLockOptions(), dialect );
-		
 		return getFactory().getSettings().isCommentsEnabled() ?
 				prependComment( sql, parameters ) : sql;
 	}
@@ -700,9 +721,9 @@
 //
 // Would need to change the way the max-row stuff is handled (i.e. behind an interface) so
 // that I could do the control breaking at the means to know when to stop
+
+		final EntityKey optionalObjectKey = getOptionalObjectKey( queryParameters, session );
 		final LockOptions[] lockOptionsArray = getLockOptions( queryParameters.getLockOptions() );
-		final EntityKey optionalObjectKey = getOptionalObjectKey( queryParameters, session );
-
 		final boolean createSubselects = isSubselectLoadingEnabled();
 		final List subselectResultKeys = createSubselects ? new ArrayList() : null;
 		final List results = new ArrayList();

Modified: core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java	2009-12-11 12:40:05 UTC (rev 18208)
+++ core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java	2009-12-11 13:23:17 UTC (rev 18209)
@@ -25,9 +25,7 @@
 package org.hibernate.loader;
 
 import java.util.Map;
-import java.util.Set;
 
-import org.hibernate.LockMode;
 import org.hibernate.LockOptions;
 import org.hibernate.dialect.Dialect;
 import org.hibernate.engine.SessionFactoryImplementor;

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java	2009-12-11 12:40:05 UTC (rev 18208)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java	2009-12-11 13:23:17 UTC (rev 18209)
@@ -257,9 +257,11 @@
 	}
 
 	public <A> A find(Class<A> entityClass, Object  primaryKey, LockModeType lockModeType, Map<String, Object> properties) {
+		LockOptions lockOptions = null;
 		try {
 			if ( lockModeType != null )
-				return ( A ) getSession().get( entityClass, ( Serializable ) primaryKey, getLockRequest(lockModeType, properties) );
+				return ( A ) getSession().get( entityClass, ( Serializable ) primaryKey,
+					( lockOptions = getLockRequest(lockModeType, properties) ) );
 			else
 				return ( A ) getSession().get( entityClass, ( Serializable ) primaryKey );
 		}
@@ -281,7 +283,7 @@
 			throw new IllegalArgumentException( e.getMessage(), e );
 		}
 		catch ( HibernateException he ) {
-			throw convert( he );
+			throw convert( he , lockOptions );
 		}
 	}
 
@@ -351,12 +353,13 @@
 
 	public void refresh(Object entity, LockModeType lockModeType, Map<String, Object> properties) {
 		checkTransactionNeeded();
+		LockOptions lockOptions = null;
 		try {
 			if ( !getSession().contains( entity ) ) {
 				throw new IllegalArgumentException( "Entity not managed" );
 			}
 			if(lockModeType != null)
-				getSession().refresh( entity, getLockRequest(lockModeType, properties) );
+				getSession().refresh( entity, (lockOptions = getLockRequest(lockModeType, properties) ) );
 			else
 				getSession().refresh( entity );
 		}
@@ -364,7 +367,7 @@
 			throw new IllegalArgumentException( e.getMessage(), e );
 		}
 		catch ( HibernateException he ) {
-			throw convert( he );
+			throw convert( he, lockOptions);
 		}
 	}
 
@@ -515,6 +518,7 @@
 	}
 
 	public void lock(Object entity, LockModeType lockModeType, Map<String, Object> properties) {
+		LockOptions lockOptions = null;
 		try {
 			if ( !isTransactionInProgress() ) {
 				throw new TransactionRequiredException( "no transaction is in progress" );
@@ -523,10 +527,10 @@
 			if ( !contains( entity ) ) {
 				throw new IllegalArgumentException( "entity not in the persistence context" );
 			}
-			getSession().buildLockRequest(getLockRequest(lockModeType, properties)).lock( entity );
+			getSession().buildLockRequest( (lockOptions = getLockRequest(lockModeType, properties))).lock( entity );
 		}
 		catch ( HibernateException he ) {
-			throw convert( he );
+			throw convert( he , lockOptions);
 		}
 
 	}
@@ -835,18 +839,25 @@
 	 * {@inheritDoc}
 	 */
 	public RuntimeException convert(HibernateException e) {
+		return convert(e, null);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public RuntimeException convert(HibernateException e, LockOptions lockOptions) {
 		if ( e instanceof StaleStateException ) {
 			PersistenceException converted = wrapStaleStateException( ( StaleStateException ) e );
 			handlePersistenceException( converted );
 			return converted;
 		}
 		else if ( e instanceof org.hibernate.OptimisticLockException ) {
-			PersistenceException converted = wrapLockException(e);
+			PersistenceException converted = wrapLockException(e, lockOptions);
 			handlePersistenceException( converted );
 			return converted;
 		}
 		else if ( e instanceof org.hibernate.PessimisticLockException ) {
-			PersistenceException converted = wrapLockException(e); 
+			PersistenceException converted = wrapLockException(e, lockOptions); 
 			handlePersistenceException( converted );
 			return converted;
 		}
@@ -925,7 +936,7 @@
 		return pe;
 	}
 
-	public PersistenceException wrapLockException(HibernateException e) {
+	public PersistenceException wrapLockException(HibernateException e, LockOptions lockOptions) {
 		PersistenceException pe;
 		if ( e instanceof org.hibernate.OptimisticLockException ) {
 			 org.hibernate.OptimisticLockException ole = (org.hibernate.OptimisticLockException)e;
@@ -933,7 +944,13 @@
 		}
 		else if ( e instanceof org.hibernate.PessimisticLockException ) {
 			  org.hibernate.PessimisticLockException ple = (org.hibernate.PessimisticLockException)e;
-			pe = new PessimisticLockException(ple.getMessage(), ple, ple.getEntity());
+			if (lockOptions !=null && lockOptions.getTimeOut() > -1) {
+				// assume lock timeout occurred if a timeout or NO WAIT was specified 
+				pe = new LockTimeoutException(ple.getMessage(), ple, ple.getEntity());
+			}
+			else {
+				pe = new PessimisticLockException(ple.getMessage(), ple, ple.getEntity());
+			}
 		}
 		else {
 			pe = new OptimisticLockException( e );

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/HibernateEntityManagerImplementor.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/HibernateEntityManagerImplementor.java	2009-12-11 12:40:05 UTC (rev 18208)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/HibernateEntityManagerImplementor.java	2009-12-11 13:23:17 UTC (rev 18209)
@@ -27,6 +27,7 @@
 
 import org.hibernate.HibernateException;
 import org.hibernate.StaleStateException;
+import org.hibernate.LockOptions;
 
 /**
  * Additional internal contracts for the Hibernate {@link javax.persistence.EntityManager} implementation.
@@ -64,8 +65,20 @@
 	 * Any appropriate/needed calls to {@link #handlePersistenceException} are also made.
 	 *
 	 * @param e The Hibernate excepton.
+	 * @param lockOptions The lock options in effect at the time of exception (can be null)
 	 * @return The JPA-specified exception
 	 */
+	public RuntimeException convert(HibernateException e, LockOptions lockOptions);
+
+	/**
+	 * Converts a Hibernate-specific exception into a JPA-specified exception; note that the JPA sepcification makes use
+	 * of exceptions outside its exception hierarchy, though they are all runtime exceptions.
+	 * <p/>
+	 * Any appropriate/needed calls to {@link #handlePersistenceException} are also made.
+	 *
+	 * @param e The Hibernate excepton.
+	 * @return The JPA-specified exception
+	 */
 	public RuntimeException convert(HibernateException e);
 
 	/**



More information about the hibernate-commits mailing list