У меня есть приложение 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?
добавил объект класс – jdog
Добавил информацию отображений ут. Я думаю, проблема может заключаться в том, что FileToSync не является «владельцем» отношения с Transaction, попытается удалить его и посмотреть, устраняет ли это проблему. Я не использую метод clear() в любом месте. – jdog
Отмените это, я использую clear() !! – jdog