2015-05-15 36 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名位置的实体,相关司机实体应该改变。

[学说\ ORM \ ORMInvalidArgumentException]
一个新的实体是通过关系找到:但是,一旦通过教义管理和下面的异常被抛出,因为它得到第101次迭代无法识别驱动器实体 未配置为级联的'AppBundle \ Entity \ Position#driver' 实体的持续操作: AppBundle \ Entity \ Driver @ 000000003412a11000007f77533bcf9d。要解决 此问题:显式调用此未知实体上的EntityManager#persist()或配置级联在 映射中保留此关联,例如@ManyToOne(..,cascade = {“persist”})。如果您不能 找出哪个实体导致问题实施 'AppBundle \ Entity \ Driver #__ toString()'以获得线索。

UPDATE

它是导致问题的循环内的flushclear

带循环上方驱动程序实体的前100个位置实体被正确保存。

当我改变

$position->setDriver($driver[0]); 

$position->setDriver($driverRepo->find($driver[0]->getId())); 

它的工作原理。

关于如何解决这个问题的任何建议?

更新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'属性吗?如果是的话,你真的需要它吗?如果你在'if(!($ number%100)){'之后执行'var_dump($ driver [0])',那么只显示'Driver'类。 – 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)]; 
    } 

只在命令结束时调用清除。 如果你担心内存消耗,那么只清除某些实体(你的情况下的$ position),但是你必须将它们保存在一个数组中,然后遍历它并使用$ this-em-> clear( $ position))