Hi all,
I've written a patch for this based on hay7777's post.
Well, I actually wrote a subclass of Configuration and inserted the code snippet below into the 2nd while loop of the overridden generateSchemaUpdateScript() method.
Code:
// Hack that generates indexes that are omitted when using 
// hibernate.hbm2ddl.auto=update. See commented-out code below.
Iterator idxIter = table.getIndexIterator();
while (idxIter.hasNext()) {
   Index index = (Index) idxIter.next();
   
   // Skip if index already exists
   if (tableInfo != null) {
      IndexMetadata meta = tableInfo.getIndexMetadata(index.getName());
      if (meta != null) {
         continue;
      }
   }
   
   script.add(index.sqlCreateString(dialect,
                                    getMapping(),
                                    defaultCatalog,
                                    defaultSchema));
}
Below is the entire source code of my DBConfiguration class. It's a bit kludgey, I know.
Code:
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeMap;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.engine.Mapping;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.IdentifierCollection;
import org.hibernate.mapping.Index;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.Table;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
import org.hibernate.tool.hbm2ddl.IndexMetadata;
import org.hibernate.tool.hbm2ddl.TableMetadata;
import org.hibernate.util.ArrayHelper;
public class DBConfiguration extends Configuration {
   
   /**
    * Generate DDL for altering tables
    *
    * @see org.hibernate.tool.hbm2ddl.SchemaUpdate
    */
   public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata) 
         throws HibernateException {
      
      secondPassCompile();
      String defaultCatalog = getProperties().getProperty(Environment.DEFAULT_CATALOG);
      String defaultSchema = getProperties().getProperty(Environment.DEFAULT_SCHEMA);
      ArrayList script = new ArrayList( 50 );
      Iterator iter = getTableMappings();
      while ( iter.hasNext() ) {
         Table table = ( Table ) iter.next();
         if ( table.isPhysicalTable() ) {
            TableMetadata tableInfo = databaseMetadata.getTableMetadata( table.getName(),
                  table.getSchema(),
                  table.getCatalog() );
            if ( tableInfo == null ) {
               script.add( table.sqlCreateString(
                     dialect,
                     getMapping(),
                     defaultCatalog,
                     defaultSchema ) );
            }
            else {
               Iterator subiter = table.sqlAlterStrings(
                     dialect,
                     getMapping(),
                     tableInfo,
                     defaultCatalog,
                     defaultSchema );
               while ( subiter.hasNext() ) script.add( subiter.next() );
            }
            Iterator comments = table.sqlCommentStrings(dialect, defaultCatalog, defaultSchema);
            while ( comments.hasNext() ) {
               script.add( comments.next() );
            }
            
         }
      }
      iter = getTableMappings();
      while ( iter.hasNext() ) {
         Table table = ( Table ) iter.next();
         if ( table.isPhysicalTable() ) {
            TableMetadata tableInfo = databaseMetadata.getTableMetadata( table.getName(),
                  table.getSchema(),
                  table.getCatalog() );
            // Hack that generates indexes that are omitted when using 
            // hibernate.hbm2ddl.auto=update. See commented-out code below.
            Iterator idxIter = table.getIndexIterator();
            while (idxIter.hasNext()) {
               Index index = (Index) idxIter.next();
               
               // Skip if index already exists
               if (tableInfo != null) {
                  IndexMetadata meta = tableInfo.getIndexMetadata(index.getName());
                  if (meta != null) {
                     continue;
                  }
               }
               
               script.add(index.sqlCreateString(dialect,
                                                getMapping(),
                                                defaultCatalog,
                                                defaultSchema));
            }
            if ( dialect.hasAlterTable() ) {
               Iterator subIter = table.getForeignKeyIterator();
               while ( subIter.hasNext() ) {
                  ForeignKey fk = ( ForeignKey ) subIter.next();
                  if ( fk.isPhysicalConstraint() ) {
                     boolean create = tableInfo == null || (
                           tableInfo.getForeignKeyMetadata( fk.getName() ) == null && (
                           //Icky workaround for MySQL bug:
                           !( dialect instanceof MySQLDialect ) ||
                           tableInfo.getIndexMetadata( fk.getName() ) == null
                           )
                           );
                     if ( create ) script.add( fk.sqlCreateString(
                           dialect,
                           getMapping(),
                           defaultCatalog,
                           defaultSchema ) );
                  }
               }
            }
         }
            /*//broken, 'cos we don't generate these with names in SchemaExport
            subIter = table.getIndexIterator();
            while ( subIter.hasNext() ) {
                Index index = (Index) subIter.next();
                if ( !index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey() ) {
                    if ( tableInfo==null || tableInfo.getIndexMetadata( index.getFilterName() ) == null ) {
                        script.add( index.sqlCreateString(dialect, mapping) );
                    }
                }
            }
            //broken, 'cos we don't generate these with names in SchemaExport
            subIter = table.getUniqueKeyIterator();
            while ( subIter.hasNext() ) {
                UniqueKey uk = (UniqueKey) subIter.next();
                if ( tableInfo==null || tableInfo.getIndexMetadata( uk.getFilterName() ) == null ) {
                    script.add( uk.sqlCreateString(dialect, mapping) );
                }
            }*/
      }
      iter = iterateGenerators( dialect );
      while ( iter.hasNext() ) {
         PersistentIdentifierGenerator generator = ( PersistentIdentifierGenerator ) iter.next();
         Object key = generator.generatorKey();
         if ( !databaseMetadata.isSequence( key ) && !databaseMetadata.isTable( key ) ) {
            String[] lines = generator.sqlCreateStrings( dialect );
            for ( int i = 0; i < lines.length; i++ ) script.add( lines[i] );
         }
      }
      
      return ArrayHelper.toStringArray( script );
   }
   
    private Iterator iterateGenerators(Dialect dialect) throws MappingException {
        TreeMap generators = new TreeMap();
        String defaultCatalog = getProperties().getProperty(Environment.DEFAULT_CATALOG);
        String defaultSchema = getProperties().getProperty(Environment.DEFAULT_SCHEMA);
        Iterator iter = classes.values().iterator();
        while ( iter.hasNext() ) {
            PersistentClass pc = ( PersistentClass ) iter.next();
            if ( !pc.isInherited() ) {
                IdentifierGenerator ig = pc.getIdentifier()
                    .createIdentifierGenerator( 
                            dialect, 
                            defaultCatalog,
                            defaultSchema,
                            (RootClass) pc
                    );
                if ( ig instanceof PersistentIdentifierGenerator ) {
                    generators.put( ( ( PersistentIdentifierGenerator ) ig ).generatorKey(), ig );
                }
            }
        }
        iter = collections.values().iterator();
        while ( iter.hasNext() ) {
            Collection collection = ( Collection ) iter.next();
            if ( collection.isIdentified() ) {
                IdentifierGenerator ig = ( ( IdentifierCollection ) collection ).getIdentifier()
                        .createIdentifierGenerator( 
                                dialect, 
                                defaultCatalog,
                                defaultSchema,
                                null
                        );
                if ( ig instanceof PersistentIdentifierGenerator ) {
                    generators.put( ( ( PersistentIdentifierGenerator ) ig ).generatorKey(), ig );
                }
            }
        }
        return generators.values().iterator();
    }
    
    protected Mapping getMapping() throws HibernateException {
      Mapping m = null;
      try {
         Field f = Configuration.class.getDeclaredField("mapping");
         f.setAccessible(true);
         m = (Mapping) f.get(this);
      } catch (Exception x) {
         throw new HibernateException("failed to reflect mapping field", x);
      }
      return m;
   }
}
I've tested it on MySQL 4.1.7 (InnoDBDialect) and haven't encountered any issue yet.
Let me know if it works for you guys.
Luke