Author: steve.ebersole(a)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.
Show replies by date