FileDocCategorySizeDatePackage
MultiTableUpdateExecutor.javaAPI DocHibernate 3.2.56122Thu Mar 15 05:38:26 GMT 2007org.hibernate.hql.ast.exec

MultiTableUpdateExecutor

public class MultiTableUpdateExecutor extends AbstractStatementExecutor
Implementation of MultiTableUpdateExecutor.
author
Steve Ebersole

Fields Summary
private static final Log
log
private final org.hibernate.persister.entity.Queryable
persister
private final String
idInsertSelect
private final String[]
updates
private final org.hibernate.param.ParameterSpecification[]
hqlParameters
Constructors Summary
public MultiTableUpdateExecutor(org.hibernate.hql.ast.HqlSqlWalker walker)


	   
		super( walker, log );

		if ( !walker.getSessionFactoryHelper().getFactory().getDialect().supportsTemporaryTables() ) {
			throw new HibernateException( "cannot perform multi-table updates using dialect not supporting temp tables" );
		}

		UpdateStatement updateStatement = ( UpdateStatement ) walker.getAST();
		FromElement fromElement = updateStatement.getFromClause().getFromElement();
		String bulkTargetAlias = fromElement.getTableAlias();
		this.persister = fromElement.getQueryable();

		this.idInsertSelect = generateIdInsertSelect( persister, bulkTargetAlias, updateStatement.getWhereClause() );
		log.trace( "Generated ID-INSERT-SELECT SQL (multi-table update) : " +  idInsertSelect );

		String[] tableNames = persister.getConstraintOrderedTableNameClosure();
		String[][] columnNames = persister.getContraintOrderedTableKeyColumnClosure();

		String idSubselect = generateIdSubselect( persister );
		List assignmentSpecifications = walker.getAssignmentSpecifications();

		updates = new String[tableNames.length];
		hqlParameters = new ParameterSpecification[tableNames.length][];
		for ( int tableIndex = 0; tableIndex < tableNames.length; tableIndex++ ) {
			boolean affected = false;
			List parameterList = new ArrayList();
			Update update = new Update( getFactory().getDialect() )
					.setTableName( tableNames[tableIndex] )
					.setWhere( "(" + StringHelper.join( ", ", columnNames[tableIndex] ) + ") IN (" + idSubselect + ")" );
			if ( getFactory().getSettings().isCommentsEnabled() ) {
				update.setComment( "bulk update" );
			}
			final Iterator itr = assignmentSpecifications.iterator();
			while ( itr.hasNext() ) {
				final AssignmentSpecification specification = ( AssignmentSpecification ) itr.next();
				if ( specification.affectsTable( tableNames[tableIndex] ) ) {
					affected = true;
					update.appendAssignmentFragment( specification.getSqlAssignmentFragment() );
					if ( specification.getParameters() != null ) {
						for ( int paramIndex = 0; paramIndex < specification.getParameters().length; paramIndex++ ) {
							parameterList.add( specification.getParameters()[paramIndex] );
						}
					}
				}
			}
			if ( affected ) {
				updates[tableIndex] = update.toStatementString();
				hqlParameters[tableIndex] = ( ParameterSpecification[] ) parameterList.toArray( new ParameterSpecification[0] );
			}
		}
	
Methods Summary
public intexecute(org.hibernate.engine.QueryParameters parameters, org.hibernate.engine.SessionImplementor session)

		coordinateSharedCacheCleanup( session );

		createTemporaryTableIfNecessary( persister, session );

		try {
			// First, save off the pertinent ids, as the return value
			PreparedStatement ps = null;
			int resultCount = 0;
			try {
				try {
					ps = session.getBatcher().prepareStatement( idInsertSelect );
					int parameterStart = getWalker().getNumberOfParametersInSetClause();
					List allParams = getWalker().getParameters();
					Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
					int sum = 1; // jdbc params are 1-based
					while ( whereParams.hasNext() ) {
						sum += ( ( ParameterSpecification ) whereParams.next() ).bind( ps, parameters, session, sum );
					}
					resultCount = ps.executeUpdate();
				}
				finally {
					if ( ps != null ) {
						session.getBatcher().closeStatement( ps );
					}
				}
			}
			catch( SQLException e ) {
				throw JDBCExceptionHelper.convert(
						getFactory().getSQLExceptionConverter(),
				        e,
				        "could not insert/select ids for bulk update",
				        idInsertSelect
					);
			}

			// Start performing the updates
			for ( int i = 0; i < updates.length; i++ ) {
				if ( updates[i] == null ) {
					continue;
				}
				try {
					try {
						ps = session.getBatcher().prepareStatement( updates[i] );
						if ( hqlParameters[i] != null ) {
							int position = 1; // jdbc params are 1-based
							for ( int x = 0; x < hqlParameters[i].length; x++ ) {
								position += hqlParameters[i][x].bind( ps, parameters, session, position );
							}
						}
						ps.executeUpdate();
					}
					finally {
						if ( ps != null ) {
							session.getBatcher().closeStatement( ps );
						}
					}
				}
				catch( SQLException e ) {
					throw JDBCExceptionHelper.convert(
							getFactory().getSQLExceptionConverter(),
					        e,
					        "error performing bulk update",
					        updates[i]
						);
				}
			}

			return resultCount;
		}
		finally {
			dropTemporaryTableIfNecessary( persister, session );
		}
	
public org.hibernate.persister.entity.QueryablegetAffectedQueryable()

		return persister;
	
protected org.hibernate.persister.entity.Queryable[]getAffectedQueryables()

		return new Queryable[] { persister };
	
public java.lang.String[]getSqlStatements()

		return updates;