1

Let's say I have the following entities:

App\Entity\MainEntity:

  /**
   * @var object
   *
   * @ORM\OneToOne(targetEntity="App\Entity\DependentEntity", fetch="EAGER")
   * @ORM\JoinColumn(name="DependentEntityType1FK", referencedColumnName="DependentEntityIDPK")
   */
  private $dependentEntityType1;

  /**
   * @var object
   *
   * @ORM\OneToOne(targetEntity="App\Entity\DependentEntity", fetch="EAGER")
   * @ORM\JoinColumn(name="DependentEntityType2FK", referencedColumnName="DependentEntityIDPK")
   */
  private $dependentEntityType2;

Basically, one-directional 1:1 relationship from main entity to the same dependent entity using two different columns in the main entity table.

It doesn't matter, whether I use fetch="EAGER" or normal lazy loading through Doctrine proxy classes, when I do something like this:

  $mainEntity = $this->mainEntityRepository->find(74);
  $mainEntity->setDependentEntityType1($this->dependentEntityRepository->find(35));
  $this->mainEntityRepository->saveTest($mainEntity);

where ::saveTest() is:

  public function saveTest(MainEntity $mainEntity) {
    $this->_em->persist($mainEntity->getDependentEntityType1());
    $this->_em->merge($mainEntity);
    $this->_em->flush();
  }

it always tries to INSERT a new dependent entity to the table, even though I never made any changes (and even if I made them, it should have been UPDATE! for it)

The question is: why does Doctrine decide this dependent entity is a new one if I did $this->dependentEntityRepository->find(35) , so loaded an existing one?

I tried fetch="EAGER" thinking that spl_object_hash might return different hashes for a Proxy class instance and the actual DependantEntity one, but it doesn't matter, the DependantEntity is for some reason always considered as "new".

UPDATE: here is the code of ::setDependentEntityType1()

  public function setDependentEntityType1(DependentEntity $dependentEntity) : void {
    $this->dependentEntity = $dependentEntity;
  }
Alexey
  • 3,414
  • 7
  • 26
  • 44
  • [Owning](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/unitofwork-associations.html) Side? https://stackoverflow.com/questions/13346233/what-is-the-owning-side-and-inverse-side-in-the-doctrine-2-doc-example – ficuscr Sep 04 '19 at 19:56
  • 1
    Thanks @ficuscr! The problem is this is a unidirectional relationship, so the dependent entity doesn't have a column with `main_enttity_id`, we don't need a property in it to contain a reference to the main entity and therefore I can't place anything into `inversedBy` of the owning (main entity) side – Alexey Sep 04 '19 at 20:31
  • Awesome. Smelled familiar but got sleepy reading the docs (ORMs do that to me) so I didn't want to wager an answer. Glad you made sense of it! – ficuscr Sep 04 '19 at 20:32
  • sorry for misunderstanding, I meant thanking for your comment :) but the problem is still there. I just explained I cannot put anything into inversedBy as there is nothing in the dependent entities pointing to the main one as it's unidirectional mapping – Alexey Sep 04 '19 at 20:35
  • *Whoosh*. See what I meant :) Can you shed more light on what the function `setDependentEntityType1` does? Something seems weird here. I've never once written anything like this in Doctrine. FYI `merge` is supposed to be removed in [Doctrine3](https://github.com/doctrine/orm/blob/master/UPGRADE.md). – ficuscr Sep 04 '19 at 20:41
  • sure, see my update. `merge()` call was just a test in hundreds of other attempts. I can remove it, replace with `persist()` , but the problem recognizing existing dependent entity as "new" remains :( – Alexey Sep 04 '19 at 20:43
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/198971/discussion-between-ficuscr-and-alexey). – ficuscr Sep 04 '19 at 20:49

0 Answers0