Мои объекты: водитель и позиция. Водитель может иметь много позиций (данные gps). У меня также есть метод в репирах моих драйверов, который дает мне все драйверы с их последней позицией.Доктрина, утерявшая стойкость состояние организации
public function getDriversWithCurrentPosition()
{
$qb = $this->createQueryBuilder('d');
$qb
->select('d, p.lat, p.lng')
->leftJoin('d.positions', 'p')
->where('p.timeCreated = (SELECT MAX(p2.timeCreated) FROM AppBundle\Entity\Position p2 WHERE p2.driver = d) OR p.timeCreated IS NULL')
->groupBy('p.driver')
;
return $qb->getQuery()->getResult();
}
Теперь я написал команду symfony для генерации случайных позиций для всех существующих драйверов. Команда генерирует, скажем, 1000 позиционных объектов и флеши после каждых 100 итераций, а также случайным образом изменяет связанный драйвер.
/**
* The returned drivers array looks like this:
* [
* [0 => driver-entity, 'lat' => 52.5634, 'lng' => 8.4535],
* [0 => driver-entity, 'lat' => 52.7434, 'lng' => 8.3434],
* ...
* ]
*/
$drivers = $driverRepo->getDriversWithCurrentPosition();
$driver = $drivers ? $drivers[0] : null;
$number = 1000;
while ($number) {
// generate new lat/lng based on drivers current position
$lat = $driver['lat'] + ...;
$lng = $driver['lng'] + ...;
// creating new entity
$position = new Position();
$position->setDriver($driver[0]);
$position->setLat($lat);
$position->setLng($lng);
$this->em->persist($position);
if (!($number % 100)) {
$this->em->flush();
$this->em->clear();
// change driver
$driver = $drivers[rand(0, count($drivers) - 1)];
}
$number--;
}
$this->em->flush();
$this->em->clear();
Таким образом, каждые 100 позиционных объектов, сгенерированных этой командой, связанный с ним элемент управления должен измениться. Но как только он попадает в 101-й итерации сущность водитель не признается управляется доктриной и следующее исключение:
[Учение \ ORM \ ORMInvalidArgumentException]
Новый объект был найден через отношения «AppBundle \ Entity \ Position # driver», который не был настроен на каскад Операции сохранения для объекта: AppBundle \ Entity \ Driver @ 000000003412a11000007f77533bcf9d. Чтобы решить проблему , выполните следующие действия: либо явно вызовите EntityManager # persist() в этом неизвестном объекте или сконфигурируйте каскад, сохраняя эту связь в сопоставлении , например @ManyToOne (.., cascade = {"persist"}). Если вы не можете выяснить, какой объект вызывает проблему, выполните команду 'AppBundle \ Entity \ Driver #__ toString()', чтобы получить ключ.
ОБНОВЛЕНИЕ
Это flush
и clear
внутри цикла, что вызывает проблему.
Первые 100 позиционных объектов с сущностью драйвера выше цикла сохраняются правильно.
Когда я изменяю
$position->setDriver($driver[0]);
в
$position->setDriver($driverRepo->find($driver[0]->getId()));
это работает.
Любые предложения по тому, как это решить?
UPDATE 2
Быстрое исправление освежает массив драйверов в LOPP:
if (!($number % 100)) {
$this->em->flush();
$this->em->clear();
// change driver
$drivers = $driverRepo->getDriversWithCurrentPosition();
$driver = $drivers[rand(0, count($drivers) - 1)];
}
У вас есть свойство 'position' внутри класса' Drive'? Если да, то вам это действительно нужно? Отображается только класс 'Driver', если вы делаете' var_dump ($ driver [0]) 'after' if (! ($ Number% 100)) {'? – Manolo
Я просто понял, что это не имеет ничего общего с изменением сущности драйвера. Это флеш и ясность. –