protected function getIdentifier($entity, $single = false)
    {
        $this->validateEntity($entity, __METHOD__);

        $entityClass   = ClassUtils::getClass($entity);
        $entityManager = $this->getEntityManager();
        $metadata      = $entityManager->getClassMetadata($entityClass);

        $metadata->validateIdentifier();

        $id = $metadata->getIdentifierValues($entity);

        /** @noinspection IsEmptyFunctionUsageInspection */
        if (empty($id)) {
            return $single ? reset($id) : $id;
        }

        foreach ($id as $field => &$idValue) {
            if (is_object($idValue)
                && $entityManager->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($idValue))
            ) {
                $singleId = $entityManager->getUnitOfWork()->getSingleIdentifierValue($idValue);

                if ($singleId === null) {
                    throw ORMInvalidArgumentException::invalidIdentifierBindingEntity();
                }

                $idValue = $singleId;
            }

            if (!in_array($field, $metadata->identifier, true)) {
                throw ORMException::missingIdentifierField($metadata->name, $field);
            }
        }

        unset($idValue);

        if (count($metadata->identifier) !== count($id)) {
            throw ORMException::unrecognizedIdentifierFields(
                $metadata->name, array_diff($metadata->identifier, $id)
            );
        }

        return $single ? reset($id) : $id;
    }