Bug Report
| Q |
A |
| BC Break |
yes/no? |
| Version |
2.4 |
| Platform |
Windows 10 |
Summary
This has been rather difficult to diagnose especially as I was dealing with some complicated layered code. If I was sure, I would have filed a bug with Doctrine before now, but I wanted to first make sure I'm not making some glaring mistake or such, in implementation, so I posted a question on StackOverflow, first, but still have no answer.
I have painstakingly tried to reduce the code to a simplified working example. On my test database tables, there are additional columns that are not referred to in the demo code.
Current behavior
// src/Entity/Record.php
declare(strict_types = 1);
namespace App\Entity;
use App\Repository\RecordRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=RecordRepository::class)
* @ORM\Table(name="Records")
*/
class Record {
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
protected $id;
public function getId(): ?int {
return $this->id;
}
/**
* @ORM\OneToOne(targetEntity="App\Entity\RecordStatus", mappedBy="record", cascade={"persist"})
* @ORM\JoinColumn(name="Id")
*/
private ?RecordStatus $recordStatus = NULL;
public function getRecordStatus(): ?RecordStatus {
return $this->recordStatus;
}
public function setRecordStatus(RecordStatus $value): void {
$value->setRecord($this);
$this->recordStatus = $value;
}
}
// src/Entity/RecordStatus.php
declare(strict_types = 1);
namespace App\Entity;
use App\Repository\RecordStatusRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=RecordStatusRepository::class)
* @ORM\Table(name="Record_Statuses")
*/
class RecordStatus {
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
protected $id;
public function getId(): ?int {
return $this->id;
}
/**
* @ORM\OneToOne(targetEntity="App\Entity\Record", inversedBy="record")
* @ORM\JoinColumn(name="RecordId")
*/
private Record $record;
public function getRecord(): Record {
return $this->record;
}
public function setRecord(Record $value): void {
$this->record = $value;
}
}
// src/Controller/DefaultController.php
declare(strict_types = 1);
namespace App\Controller;
use App\Entity\Record;
use App\Entity\RecordStatus;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class DefaultController extends AbstractController {
/**
* @Route("/")
*/
public function home(): Response {
$doctrine = $this->getDoctrine();
$entityManager = $doctrine->getManager();
$recordRepository = $doctrine->getRepository(Record::class);
$recordStatus = new RecordStatus;
$item = $recordRepository->find(1);
$item->setRecordStatus($recordStatus);
$entityManager->flush();
return new JsonResponse(['id' => $item->getId()]);
}
}
When this route ("/") is triggered, the record is updated and the old Id is displayed. But after the update, checking the database shows that the record now has a newly Auto-Generated Id, that comes after the last previous record in the table. Note that this is on UPDATE and not INSERT. The above is, as shown, OneToOne. I haven't yet checked whether the same issue occurs for OneToMany/ManyToOne Associations.
Of course, I realize this occurs because I'm using a new Associated child entity here, and can work around this by using an existing child object if any, but there may be a use case for a new child association (esp. if one wasn't assigned on persisting new parent Record), depending on application requirements, so a proper solution is needed anyway, I think.
How to reproduce
Please see above code samples and below:
CREATE TABLE Records (
Id bigint UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
, CreatedAt timestamp NOT NULL DEFAULT NOW()
, CreatedBy int UNSIGNED NOT NULL
, Description varchar(4094) COLLATE latin1_general_ci NOT NULL
) CHARSET=latin1 COLLATE=latin1_bin;
CREATE TABLE Record_Statuses (
Id bigint UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
, RecordId bigint UNSIGNED NOT NULL
, CreatedAt timestamp NOT NULL DEFAULT NOW()
, UpdatedAt timestamp NOT NULL DEFAULT NOW()
, CreatedBy int UNSIGNED NOT NULL
, UpdatedBy int UNSIGNED NOT NULL
, RecordStateId tinyint UNSIGNED NOT NULL
) CHARSET=latin1 COLLATE=latin1_bin;
These tables and above code are not completely compatible AS IS. Shown here in full, if necessary to help resolve the issue or if relevant in any way. You may need to exclude some columns, or add dummy columns to the entities in above code.
Expected behavior
(Record/row) Id should not be altered during update.
One urgent project of mine is held up due to this issue. Any assistance/clarification is appreciated.
Thank you.
Bug Report
Summary
This has been rather difficult to diagnose especially as I was dealing with some complicated layered code. If I was sure, I would have filed a bug with Doctrine before now, but I wanted to first make sure I'm not making some glaring mistake or such, in implementation, so I posted a question on StackOverflow, first, but still have no answer.
I have painstakingly tried to reduce the code to a simplified working example. On my test database tables, there are additional columns that are not referred to in the demo code.
Current behavior
When this route ("/") is triggered, the record is updated and the old Id is displayed. But after the update, checking the database shows that the record now has a newly Auto-Generated Id, that comes after the last previous record in the table. Note that this is on UPDATE and not INSERT. The above is, as shown, OneToOne. I haven't yet checked whether the same issue occurs for OneToMany/ManyToOne Associations.
Of course, I realize this occurs because I'm using a new Associated child entity here, and can work around this by using an existing child object if any, but there may be a use case for a new child association (esp. if one wasn't assigned on persisting new parent Record), depending on application requirements, so a proper solution is needed anyway, I think.
How to reproduce
Please see above code samples and below:
These tables and above code are not completely compatible AS IS. Shown here in full, if necessary to help resolve the issue or if relevant in any way. You may need to exclude some columns, or add dummy columns to the entities in above code.
Expected behavior
(Record/row) Id should not be altered during update.
One urgent project of mine is held up due to this issue. Any assistance/clarification is appreciated.
Thank you.