protected void initializeWithTableNames(Session session, Collection tableNames) {
    tableNameToClass = new Hashtable(tableNames.size());
    tableNameToPkFieldNames = new Hashtable(tableNames.size());

    // pkFieldVectors cached here to avoid calculating it more than once per class
    Hashtable classToPkFieldNames = new Hashtable();
    // loop through the descriptors to fill out tableNameToClass and tableNameToPkFieldNames
    Iterator descriptors = session.getDescriptors().values().iterator();
    while (descriptors.hasNext() && !tableNames.isEmpty()) {
      ClassDescriptor desc = (ClassDescriptor) descriptors.next();

      // Create a Vector containing names of all tables mapped to the descriptor
      Vector descTableNames = desc.getTableNames();

      // bypass descriptors with no tables
      if (descTableNames.isEmpty()) {
        continue;
      }

      // Remove schema names (if any) converting "SCHEMA_NAME.TABLE_NAME" to "TABLE_NAME"
      removePrefixFromDatabaseObjectNames(descTableNames);

      // handle inheritance: table name should be mapped to the base mapped class
      Class baseClass = desc.getJavaClass();
      while (desc.isChildDescriptor()) {
        desc = session.getDescriptor(desc.getInheritancePolicy().getParentClass());
        baseClass = desc.getJavaClass();
      }

      Iterator it = tableNames.iterator();
      while (it.hasNext()) {
        // for each tableName specified by the user
        String tableName = (String) it.next();
        // verify whether the descriptor maps a table with the same name
        if (descTableNames.contains(tableName)) {
          // map the table name to the baseClass corresponding to the descriptor
          tableNameToClass.put(tableName, baseClass);

          // try to obtain cached pkFieldNames Vector corresponding to baseClass
          Vector pkFieldNames = (Vector) classToPkFieldNames.get(baseClass);
          if (pkFieldNames == null) {
            // Create a Vector containing names of all primary key fields
            pkFieldNames = desc.getPrimaryKeyFieldNames();
            // Remove table name converting from "TABLE_NAME.FIELD_NAME" to "FIELD_NAME"
            removePrefixFromDatabaseObjectNames(pkFieldNames);
            // cache pkFieldNames Vector corresponding to baseClass
            classToPkFieldNames.put(baseClass, pkFieldNames);
          }
          // map the table name to the Vector of names of primary key fields.
          tableNameToPkFieldNames.put(tableName, pkFieldNames);

          // the table name is mapped - remove it from the list of table names to be mapped.
          it.remove();
        }
      }
    }
  }
  public CacheInvalidator(Session session) {
    // HashSet is used to avoid duplications
    HashSet tableNames = new HashSet();

    // fill out tableNames collection with all tables' names mapped by all descriptors
    Iterator descriptors = session.getDescriptors().values().iterator();
    while (descriptors.hasNext()) {
      ClassDescriptor desc = (ClassDescriptor) descriptors.next();

      // Create a Vector containing names of all tables mapped to the descriptor
      Vector descTableNames = desc.getTableNames();
      // Remove schema names (if any) converting "SCHEMA_NAME.TABLE_NAME" to "TABLE_NAME"
      removePrefixFromDatabaseObjectNames(descTableNames);
      // add descTableNames to the collection
      tableNames.addAll(descTableNames);
    }
    // initialize
    initializeWithTableNames(session, tableNames);
  }