2016-10-25 3 views
0

У меня есть приложение cli с полным стеком Symfony, которое обрабатывает файлы XLSX. Однако обновление информации в записи базы данных в 2 разных точках приводит к дублированию записи вместо обновления.doctrine entity manager duplicate insert on update

Наиболее простой пробой приложения:

Команда

class AppProcessFilesCommand extends ContainerAwareCommand 
{ 

    protected function execute(InputInterface $input, OutputInterface $output) 
    { 
     $em = $this-setContainer>getContainer()->get('doctrine')->getManager(); 
     $file = $em->getRepository('AppBundle:FileToSync')->findBy(
       ['processed' => null], 
       ['modified' => 'ASC'] 
      ); 
      if (sizeof($file) > 0) { 
       $file = $file[0]; 

       foreach (ProcessorFactory::getAvailableProcessors() as $processor) { 
        $start = microtime(true);       
        if (ProcessorFactory::getInstance($processor) 
             ->setOutput($output) 
             ->setContainer($this->getContainer()) 
             ->setDoctrine($this->getContainer()->get('doctrine')) 
             ->process($file) 
        ) { 
         $processorFound = true; 
         $file->setTimeTaken(microtime(true) - $start); 
         $file->setProcessed(new \DateTime()); 
         $em->persist($file); 
         $em->flush(); 
        } 
       } 

Обработка петли

class Processor 
{ 
    public function process($fileToSync) 
    { 
     $foundFiles = $this->convertToCsv($file); 
     $noRows = $this->processCsvSheets($foundFiles, $fileToSync); 

     $em = $this->getDoctrine()->getManager(); 
     $fileToSync->setDetectedTypeId($this->getMyFileTypeId()); 
     $fileToSync->setRowCount($noRows); 
     $em->persist($fileToSync); 
     $em->flush(); 

Entity Класс

namespace AppBundle\Entity; 


class FileToSync 
{ 
    private $id; 

    private $absolute_path; 

    private $modified; 

    private $processed; 

    /** 
    * @var int 
    */ 
    private $detected_type_id; 

    private $time_taken; 

    private $row_count; 

     /** 
    * @var \AppBundle\Entity\DetectedType 
    */ 
    private $DetectedType; 


    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set absolutePath 
    * 
    * @param string $absolutePath 
    * 
    * @return FileToSync 
    */ 
    public function setAbsolutePath($absolutePath) 
    { 
     $this->absolute_path = $absolutePath; 

     return $this; 
    } 

    /** 
    * Get absolutePath 
    * 
    * @return string 
    */ 
    public function getAbsolutePath() 
    { 
     return $this->absolute_path; 
    } 

    /** 
    * Set modified 
    * 
    * @param \DateTime $modified 
    * 
    * @return FileToSync 
    */ 
    public function setModified($modified) 
    { 
     $this->modified = $modified; 

     return $this; 
    } 

    /** 
    * Get modified 
    * 
    * @return \DateTime 
    */ 
    public function getModified() 
    { 
     return $this->modified; 
    } 

    /** 
    * Set detectedTypeId 
    * 
    * @param \integer $detectedTypeId 
    * 
    * @return FileToSync 
    */ 
    public function setDetectedTypeId($detectedTypeId) 
    { 
     $this->detected_type_id = $detectedTypeId; 

     return $this; 
    } 

    /** 
    * Get detectedTypeId 
    * 
    * @return \integer 
    */ 
    public function getDetectedTypeId() 
    { 
     return $this->detected_type_id; 
    } 

    /** 
    * Set processed 
    * 
    * @param \datetime $processed 
    * 
    * @return FileToSync 
    */ 
    public function setProcessed(\datetime $processed) 
    { 
     $this->processed = $processed; 

     return $this; 
    } 

    /** 
    * Get processed 
    * 
    * @return \datetime 
    */ 
    public function getProcessed() 
    { 
     return $this->processed; 
    } 

    /** 
    * Set detectedType 
    * 
    * @param \AppBundle\Entity\DetectedType $detectedType 
    * 
    * @return FileToSync 
    */ 
    public function setDetectedType(\AppBundle\Entity\DetectedType $detectedType = null) 
    { 
     $this->DetectedType = $detectedType; 

     return $this; 
    } 

    /** 
    * Get detectedType 
    * 
    * @return \AppBundle\Entity\DetectedType 
    */ 
    public function getDetectedType() 
    { 
     return $this->DetectedType; 
    } 

    /** 
    * Set timeTaken 
    * 
    * @param string $timeTaken 
    * 
    * @return FileToSync 
    */ 
    public function setTimeTaken($timeTaken) 
    { 
     $this->time_taken = $timeTaken; 

     return $this; 
    } 

    /** 
    * Get timeTaken 
    * 
    * @return string 
    */ 
    public function getTimeTaken() 
    { 
     return $this->time_taken; 
    } 

    /** 
    * Set rowCount 
    * 
    * @param integer $rowCount 
    * 
    * @return FileToSync 
    */ 
    public function setRowCount($rowCount) 
    { 
     $this->row_count = $rowCount; 

     return $this; 
    } 

    /** 
    * Get rowCount 
    * 
    * @return integer 
    */ 
    public function getRowCount() 
    { 
     return $this->row_count; 
    } 
} 

сущности Отображение (ет)

AppBundle\Entity\DetectedType: 
    type: entity 
    table: detected_type 
    id: 
     id: 
      type: integer 
      generator: { strategy: AUTO } 
    fields: 
     name: 
      type: string 
      length: 501 

AppBundle\Entity\FileToSync: 
    type: entity 
    table: file_to_sync 
    id: 
     id: 
      type: integer 
      generator: { strategy: AUTO } 
    manyToOne: 
     DetectedType: 
      targetEntity: DetectedType 
      joinColumn: 
       name: detected_type_id 
       referencedColumnName: id 
    fields: 
     absolute_path: 
      type: string 
      length: 255 
     modified: 
      type: datetime 
     detected_type_id: 
      type: integer 
      nullable: true 
     processed: 
      type: datetime 
      nullable: true 
     time_taken: 
      type: decimal 
      precision: 11 
      scale: 6 
      nullable: true 
     row_count: 
      type: integer 
      nullable: true 


AppBundle\Entity\Transaction: 
    type: entity 
    table: transaction 
    id: 
     id: 
      type: integer 
      generator: { strategy: AUTO } 
    uniqueConstraints: 
     txnId: 
      columns: [ txn_id ] 
    manyToOne: 
     FileToSync: 
      targetEntity: FileToSync 
      joinColumn: 
       name: file_id 
       referencedColumnName: id 
    fields: 
     txnDate: 
      type: datetime 
     file_id: 
      type: integer 

В цикле обработки, $ fileToSync не обновляются, а новая запись вставлена. Затем он обновляется в команде.

Я работаю в предположении, что $ this-> getContainer() -> get ('doctrine') -> getManager(); работает как Singleton?

ответ

1

Да, по умолчанию Symfony2 службы работают как синглтон, вы можете прочитать:

http://symfony.com/doc/2.6/cookbook/service_container/scopes.html

Понимание Scopes¶

Область действия управления службы, как долго экземпляр службы это , используемый контейнером. Компонент Dependency Injection предоставляет две общие области :

контейнер (по умолчанию): тот же экземпляр используется каждый раз, когда вы запрашиваете его из этого контейнера. Прототип: Новый экземпляр создается каждый раз, когда вы запрос на обслуживание

Firsly, вы не можете использовать упорствовать метод, если ваш объект «файл» был загружен из EntityManager. Объект второго файла дампа перед флешем и проверьте, что вы пытаетесь сохранить. Также вы можете проверить статус лица на UnitOfWork здесь образец:

$unitOfWork = $entityManager->getUnitOfWork(); 

foreach ($unitOfWork->getScheduledEntityInsertions() as $entity) { 
    #for insert 
} 

foreach ($unitOfWork->getScheduledEntityUpdates() as $entity) { 
    # for update 
} 

Семантика операции сохраняется, нанесенной на сущности X, являются следующим образом:

Если X является новым объектом, он становится управляемым. Объект X будет введен в базу данных в результате операции сброса. Если X является существующей управляемой сущностью , она игнорируется операцией persist. Однако операция сохранения каскадируется для объектов, на которые ссылается X, если отношения от X к этим другим объектам сопоставляются с cascade = PERSIST или cascade = ALL (см. «Транзитивная стойкость»).Если X является удаленным объектом, он становится управляемым. Если X является отдельным объектом, исключение будет выброшено на флеш.

Я думал, что вы представляете объект в классе, но вы не являетесь, и я не могу понять, какое отношение вы используете с «DetectedType». Этой проблема может произойти, если вы звоните «ясно» метод где-либо, если ваши имеют проблемы с отношением владеющей стороны, пожалуйста, прочитайте это:

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html

+0

добавил объект класс – jdog

+0

Добавил информацию отображений ут. Я думаю, проблема может заключаться в том, что FileToSync не является «владельцем» отношения с Transaction, попытается удалить его и посмотреть, устраняет ли это проблему. Я не использую метод clear() в любом месте. – jdog

+0

Отмените это, я использую clear() !! – jdog

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

  • Нет связанных вопросов^_^