2015-05-15 2 views
1

Мои объекты: водитель и позиция. Водитель может иметь много позиций (данные 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)]; 
} 
+0

У вас есть свойство 'position' внутри класса' Drive'? Если да, то вам это действительно нужно? Отображается только класс 'Driver', если вы делаете' var_dump ($ driver [0]) 'after' if (! ($ Number% 100)) {'? – Manolo

+0

Я просто понял, что это не имеет ничего общего с изменением сущности драйвера. Это флеш и ясность. –

ответ

0

Не ясно при промывке.

if (!($number % 100)) { 
     $this->em->flush(); 
     $this->em->clear(); <-HERE IS THE PROBLEM 
     // change driver 
     $driver = $drivers[rand(0, count($drivers) - 1)]; 
    } 

Звоните только в конце команды. Если вы обеспокоены потреблением памяти, тогда очистите только определенные объекты (позиция $ в вашем случае, но вам придется держать их в массиве, а затем перебирать по нему и очищать их с помощью $ this-em-> clear ($ position))

Смежные вопросы