[hibernate-commits] Hibernate SVN: r11116 - in trunk/Hibernate3/src/org/hibernate: loader/hql and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Jan 30 09:30:55 EST 2007


Author: steve.ebersole at jboss.com
Date: 2007-01-30 09:30:55 -0500 (Tue, 30 Jan 2007)
New Revision: 11116

Modified:
   trunk/Hibernate3/src/org/hibernate/loader/criteria/CriteriaLoader.java
   trunk/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java
   trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
   trunk/Hibernate3/src/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
   trunk/Hibernate3/src/org/hibernate/persister/entity/Lockable.java
Log:
HHH-2392 : HQL/Criteria + lockmode (joined-subclass)

Modified: trunk/Hibernate3/src/org/hibernate/loader/criteria/CriteriaLoader.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/loader/criteria/CriteriaLoader.java	2007-01-30 14:29:39 UTC (rev 11115)
+++ trunk/Hibernate3/src/org/hibernate/loader/criteria/CriteriaLoader.java	2007-01-30 14:30:55 UTC (rev 11116)
@@ -21,6 +21,7 @@
 import org.hibernate.loader.OuterJoinLoader;
 import org.hibernate.persister.entity.Loadable;
 import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.persister.entity.Lockable;
 import org.hibernate.transform.ResultTransformer;
 import org.hibernate.type.Type;
 
@@ -125,16 +126,18 @@
 			return sqlSelectString;
 		}
 
-		Map keyColumnNames = null;
-		Loadable[] persisters = getEntityPersisters();
-		String[] entityAliases = getAliases();
-		if ( dialect.forUpdateOfColumns() ) {
-			keyColumnNames = new HashMap();
-			for ( int i=0; i<entityAliases.length; i++ ) {
-				keyColumnNames.put( entityAliases[i], persisters[i].getIdentifierColumnNames() );
+		final Map aliasedLockModes = new HashMap();
+		final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null;
+		final String[] drivingSqlAliases = getAliases();
+		for ( int i = 0; i < drivingSqlAliases.length; i++ ) {
+			final Lockable drivingPersister = ( Lockable ) getEntityPersisters()[i];
+			final String sqlAlias = drivingPersister.getRootTableAlias( drivingSqlAliases[i] );
+			aliasedLockModes.put( sqlAlias, lockModes.get( drivingSqlAliases[i] ) );
+			if ( keyColumnNames != null ) {
+				keyColumnNames.put( sqlAlias, drivingPersister.getRootTableIdentifierColumnNames() );
 			}
 		}
-		return dialect.applyLocksToSql( sqlSelectString, lockModes, keyColumnNames );
+		return dialect.applyLocksToSql( sqlSelectString, aliasedLockModes, keyColumnNames );
 	}
 
 	protected LockMode[] getLockModes(Map lockModes) {

Modified: trunk/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java	2007-01-30 14:29:39 UTC (rev 11115)
+++ trunk/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java	2007-01-30 14:30:55 UTC (rev 11116)
@@ -23,6 +23,7 @@
 import org.hibernate.hql.ast.QueryTranslatorImpl;
 import org.hibernate.hql.ast.tree.FromElement;
 import org.hibernate.hql.ast.tree.SelectClause;
+import org.hibernate.hql.ast.tree.QueryNode;
 import org.hibernate.impl.IteratorImpl;
 import org.hibernate.loader.BasicLoader;
 import org.hibernate.param.ParameterSpecification;
@@ -30,6 +31,7 @@
 import org.hibernate.persister.collection.QueryableCollection;
 import org.hibernate.persister.entity.Loadable;
 import org.hibernate.persister.entity.Queryable;
+import org.hibernate.persister.entity.Lockable;
 import org.hibernate.transform.ResultTransformer;
 import org.hibernate.type.EntityType;
 import org.hibernate.type.Type;
@@ -280,34 +282,35 @@
 		if ( lockModes == null || lockModes.size() == 0 ) {
 			return sql;
 		}
-		else {
-			// can't cache this stuff either (per-invocation)
-			//we are given a map of user alias -> lock mode
-			//create a new map of sql alias -> lock mode
-			final Map aliasedLockModes = new HashMap();
-			final Iterator iter = lockModes.entrySet().iterator();
-			while ( iter.hasNext() ) {
-				Map.Entry me = ( Map.Entry ) iter.next();
-				final String userAlias = ( String ) me.getKey();
-				final String sqlAlias = (String) sqlAliasByEntityAlias.get( userAlias );
-				if (sqlAlias==null) {
-					throw new IllegalArgumentException("alias not found: " + userAlias);
-				}
-				aliasedLockModes.put( sqlAlias, me.getValue() );
-			}
 
-			//if necessary, create a map of sql alias -> key columns
-			Map keyColumnNames = null;
-			if ( dialect.forUpdateOfColumns() ) {
-				final Loadable[] persisters = getEntityPersisters();
-				keyColumnNames = new HashMap();
-				for ( int i = 0; i < sqlAliases.length; i++ ) {
-					keyColumnNames.put( sqlAliases[i], persisters[i].getIdentifierColumnNames() );
-				}
+		// can't cache this stuff either (per-invocation)
+		// we are given a map of user-alias -> lock mode
+		// create a new map of sql-alias -> lock mode
+		final Map aliasedLockModes = new HashMap();
+		final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null;
+		final Iterator iter = lockModes.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = ( Map.Entry ) iter.next();
+			final String userAlias = ( String ) me.getKey();
+			final String drivingSqlAlias = ( String ) sqlAliasByEntityAlias.get( userAlias );
+			if ( drivingSqlAlias == null ) {
+				throw new IllegalArgumentException( "could not locate alias to apply lock mode : " + userAlias );
 			}
-
-			return dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames );
+			// at this point we have (drivingSqlAlias) the SQL alias of the driving table
+			// corresponding to the given user alias.  However, the driving table is not
+			// (necessarily) the table against which we want to apply locks.  Mainly,
+			// the exception case here is joined-subclass hierarchies where we instead
+			// want to apply the lock against the root table (for all other strategies,
+			// it just happens that driving and root are the same).
+			final QueryNode select = ( QueryNode ) queryTranslator.getSqlAST();
+			final Lockable drivingPersister = ( Lockable ) select.getFromClause().getFromElement( userAlias ).getQueryable();
+			final String sqlAlias = drivingPersister.getRootTableAlias( drivingSqlAlias );
+			aliasedLockModes.put( sqlAlias, me.getValue() );
+			if ( keyColumnNames != null ) {
+				keyColumnNames.put( sqlAlias, drivingPersister.getRootTableIdentifierColumnNames() );
+			}
 		}
+		return dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames );
 	}
 
 	protected boolean upgradeLocks() {

Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java	2007-01-30 14:29:39 UTC (rev 11115)
+++ trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java	2007-01-30 14:30:55 UTC (rev 11116)
@@ -1338,6 +1338,10 @@
 		return getSubclassTableName( 0 );
 	}
 
+	public String getRootTableAlias(String drivingAlias) {
+		return drivingAlias;
+	}
+
 	public String[] getRootTableIdentifierColumnNames() {
 		return getRootTableKeyColumnNames();
 	}

Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java	2007-01-30 14:29:39 UTC (rev 11115)
+++ trunk/Hibernate3/src/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java	2007-01-30 14:30:55 UTC (rev 11116)
@@ -573,6 +573,10 @@
 		return naturalOrderTableNames[0];
 	}
 
+	public String getRootTableAlias(String drivingAlias) {
+		return generateTableAlias( drivingAlias, getTableId( getRootTableName(), tableNames ) );
+	}
+
 	public Declarer getSubclassPropertyDeclarer(String propertyPath) {
 		if ( "class".equals( propertyPath ) ) {
 			// special case where we need to force incloude all subclass joins

Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/Lockable.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/persister/entity/Lockable.java	2007-01-30 14:29:39 UTC (rev 11115)
+++ trunk/Hibernate3/src/org/hibernate/persister/entity/Lockable.java	2007-01-30 14:30:55 UTC (rev 11116)
@@ -1,7 +1,11 @@
 package org.hibernate.persister.entity;
 
 /**
- * Contract for things that can be locked via a {@link org.hibernate.dialect.lock.LockingStrategy}
+ * Contract for things that can be locked via a {@link org.hibernate.dialect.lock.LockingStrategy}.
+ * <p/>
+ * Currently only the root table gets locked, except for the case of HQL and Criteria queries
+ * against dialects which do not support either (1) FOR UPDATE OF or (2) support hint locking
+ * (in which case *all* queried tables would be locked).
  *
  * @author Steve Ebersole
  * @since 3.2
@@ -15,6 +19,16 @@
 	public String getRootTableName();
 
 	/**
+	 * Get the SQL alias this persister would use for the root table
+	 * given the passed driving alias.
+	 *
+	 * @param drivingAlias The driving alias; or the alias for the table
+	 * mapped by this persister in the hierarchy.
+	 * @return The root table alias.
+	 */
+	public String getRootTableAlias(String drivingAlias);
+
+	/**
 	 * Get the names of columns on the root table used to persist the identifier.
 	 *
 	 * @return The root table identifier column names.




More information about the hibernate-commits mailing list