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

MultiTableDeleteExecutor

public class MultiTableDeleteExecutor extends AbstractStatementExecutor
Implementation of MultiTableDeleteExecutor.
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[]
deletes
Constructors Summary
public MultiTableDeleteExecutor(org.hibernate.hql.ast.HqlSqlWalker walker)


	   
		super( walker, log );

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

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

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

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

		deletes = new String[tableNames.length];
		for ( int i = tableNames.length - 1; i >= 0; i-- ) {
			// TODO : an optimization here would be to consider cascade deletes and not gen those delete statements;
			//      the difficulty is the ordering of the tables here vs the cascade attributes on the persisters ->
			//          the table info gotten here should really be self-contained (i.e., a class representation
			//          defining all the needed attributes), then we could then get an array of those
			final Delete delete = new Delete()
					.setTableName( tableNames[i] )
					.setWhere( "(" + StringHelper.join( ", ", columnNames[i] ) + ") IN (" + idSubselect + ")" );
			if ( getFactory().getSettings().isCommentsEnabled() ) {
				delete.setComment( "bulk delete" );
			}

			deletes[i] = delete.toStatementString();
		}
	
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, saving the number of pertinent ids for return
			PreparedStatement ps = null;
			int resultCount = 0;
			try {
				try {
					ps = session.getBatcher().prepareStatement( idInsertSelect );
					Iterator paramSpecifications = getWalker().getParameters().iterator();
					int pos = 1;
					while ( paramSpecifications.hasNext() ) {
						final ParameterSpecification paramSpec = ( ParameterSpecification ) paramSpecifications.next();
						pos += paramSpec.bind( ps, parameters, session, pos );
					}
					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 delete",
				        idInsertSelect
					);
			}

			// Start performing the deletes
			for ( int i = 0; i < deletes.length; i++ ) {
				try {
					try {
						ps = session.getBatcher().prepareStatement( deletes[i] );
						ps.executeUpdate();
					}
					finally {
						if ( ps != null ) {
							session.getBatcher().closeStatement( ps );
						}
					}
				}
				catch( SQLException e ) {
					throw JDBCExceptionHelper.convert(
							getFactory().getSQLExceptionConverter(),
					        e,
					        "error performing bulk delete",
					        deletes[i]
						);
				}
			}

			return resultCount;
		}
		finally {
			dropTemporaryTableIfNecessary( persister, session );
		}
	
protected org.hibernate.persister.entity.Queryable[]getAffectedQueryables()

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

		return deletes;