/**
  * Return a list of ChangedEntity instances created at the given revision.
  *
  * @param int $revision
  * @return ChangedEntity[]
  */
 public function findEntitiesChangedAtRevision($revision)
 {
     $auditedEntities = $this->metadataFactory->getAllClassNames();
     $changedEntities = array();
     foreach ($auditedEntities as $className) {
         /** @var ClassMetadataInfo|ClassMetadata $class */
         $class = $this->em->getClassMetadata($className);
         if ($class->isInheritanceTypeSingleTable() && count($class->subClasses) > 0) {
             continue;
         }
         $tableName = $this->config->getTableName($class);
         $params = array();
         $whereSQL = "e." . $this->config->getRevisionFieldName() . " = ?";
         $columnList = "e." . $this->config->getRevisionTypeFieldName();
         $params[] = $revision;
         $columnMap = array();
         foreach ($class->fieldNames as $columnName => $field) {
             $type = Type::getType($class->fieldMappings[$field]['type']);
             $tableAlias = $class->isInheritanceTypeJoined() && $class->isInheritedField($field) && !$class->isIdentifier($field) ? 're' : 'e';
             $columnList .= ', ' . $tableAlias . '.' . $type->convertToPHPValueSQL($class->getQuotedColumnName($field, $this->platform), $this->platform) . ' AS ' . $this->platform->quoteSingleIdentifier($field);
             $columnMap[$field] = $this->platform->getSQLResultCasing($columnName);
         }
         foreach ($class->associationMappings as $assoc) {
             if (($assoc['type'] & ClassMetadata::TO_ONE) > 0 && $assoc['isOwningSide']) {
                 foreach ($assoc['targetToSourceKeyColumns'] as $sourceCol) {
                     $columnList .= ', ' . $sourceCol;
                     $columnMap[$sourceCol] = $this->platform->getSQLResultCasing($sourceCol);
                 }
             }
         }
         $joinSql = '';
         if ($class->isInheritanceTypeSingleTable()) {
             $columnList .= ', e.' . $class->discriminatorColumn['name'];
             $whereSQL .= " AND e." . $class->discriminatorColumn['fieldName'] . " = ?";
             $params[] = $class->discriminatorValue;
         } elseif ($class->isInheritanceTypeJoined() && $class->rootEntityName != $class->name) {
             $columnList .= ', re.' . $class->discriminatorColumn['name'];
             /** @var ClassMetadataInfo|ClassMetadata $rootClass */
             $rootClass = $this->em->getClassMetadata($class->rootEntityName);
             $rootTableName = $this->config->getTableName($rootClass);
             $joinSql = "INNER JOIN {$rootTableName} re ON";
             $joinSql .= " re.rev = e.rev";
             foreach ($class->getIdentifierColumnNames() as $name) {
                 $joinSql .= " AND re.{$name} = e.{$name}";
             }
         }
         $query = "SELECT " . $columnList . " FROM " . $tableName . " e " . $joinSql . " WHERE " . $whereSQL;
         $revisionsData = $this->em->getConnection()->executeQuery($query, $params);
         foreach ($revisionsData as $row) {
             $id = array();
             foreach ($class->identifier as $idField) {
                 $id[$idField] = $row[$idField];
             }
             $entity = $this->createEntity($className, $row, $revision);
             $changedEntities[] = new ChangedEntity($className, $id, $row[$this->config->getRevisionTypeFieldName()], $entity);
         }
     }
     return $changedEntities;
 }