Документы доктрины не могут быть загружены, если стратегия идентификатора NONE

#doctrine #doctrine-odm

#doctrine #doctrine-odm

Вопрос:

Я использую Doctrine с MongoDB. Обычно меня не волнуют идентификаторы, но в одном случае мне нужен идентификатор перед сбросом, чтобы избежать ненужного обхода. Поэтому я добавил стратегию ID «NONE» и установил идентификатор в конструкторе. Но после этого я не могу загрузить документ по его идентификатору.

Код для загрузки документа:

 /* @var $userRepo DocumentRepository */
$userRepo = $managerRegistry->getRepository(User::class);
$qb = $userRepo->createQueryBuilder();
$qb->field('id')->in(['5cb6377ae0b68801bc3b1771']);
$user = $qb->getQuery()->execute()->getSingleResult();
var_dump($user instanceof User);

/* @var $userRepo DocumentRepository */
$userRepo = $managerRegistry->getRepository(User::class);
$users = $userRepo->findBy(['id' => '5cb6377ae0b68801bc3b1771']);
var_dump(count($users) === 1);

/* @var $userRepo DocumentRepository */
$userRepo = $managerRegistry->getRepository(User::class);
$user = $userRepo->find('5cb6377ae0b68801bc3b1771');
var_dump($user instanceof User);
 

(На самом деле false, false, false — ожидаемое true, true, true)

Документ:

 /**
 * @ODMDocument
 */
class User
{

    /**
     * @ODMId(strategy="NONE")
     */
    protected $id;

    public function __construct()
    {
        $this->id = new MongoId();
    }

    ...
}
 

Ответ №1:

Это происходит потому, что вы используете строку в вызовах поиска. Вам нужно использовать MongoId , поскольку это ваш идентификатор. Итак:

 /* @var $userRepo DocumentRepository */
$userRepo = $managerRegistry->getRepository(User::class);
$user = $userRepo->find(new MongoId('5cb6377ae0b68801bc3b1771'));
 

Комментарии:

1. Да, это имеет смысл. Но я не хочу менять способ работы с объектами. Итак, я изменил аннотацию на @ODMId(strategy="NONE", type="string") и конструктор на $this->id = (string) new MongoId(); нее, похоже, работает нормально, но теперь — следствие — в базе данных хранится строка вместо ObjectId . Я не уверен, есть ли какие-либо побочные эффекты. Если doctrine заботится о генерации идентификатора, идентификатор объекта сохраняется в базе данных, но, тем не менее, я могу запросить строку. Что отличает doctrine внутренне?

2. Не могу сказать с головы, но это звучит как ошибка. Если бы вы могли открыть проблему в github.com/doctrine/mongodb-odm мы проведем расследование