[DDC-2585] Persisting the owning side will not set the inverse side relationship Created: 31/Jul/13  Updated: 01/Aug/13  Resolved: 31/Jul/13

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.3.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Pedro Cordeiro Assignee: Marco Pivetta
Resolution: Invalid Votes: 0
Labels: bidirectional, cascade, owning, relations


 Description   

Adding items to the owning side of a bidirectional relationship should be enough to set the items' relationship to its owner. Instead, as of now we still have to manually set both sides, be it on the entity itself or on your controller/service code.

Example:

$owning->addObject($inverse);

Doctrine should execute $inverse->setOwner($owning) when flushing $owning. Right now we have to run $owning->addObject($inverse) and $inverse->setOwner($owning) manually, which makes no sense, since Owner entity is configured to cascade persist operations.



 Comments   
Comment by Marco Pivetta [ 31/Jul/13 ]

Doctrine ORM is does just save and load VALID object graphs. It won't fix a broken object graph for you.

Comment by Pedro Cordeiro [ 31/Jul/13 ]

I add multiple objects to the owning side's collection, persist it, and when I reload it, the collection is empty (as the objects were saved without referencing the owner). This is severely counter-intuitive. If I added items to an entity's collection, persisted the entity and the entity was configured to cascade persist operations for said collection, I would expect (and lots of other people too, as I found in my google searches) the items not only to be persisted, but to remain inside the collection (meaning they would have to reference its owner). Flushing the entity manager should NOT empty my entity collections. There is ABSOLUTELY no reason to have an ->addObject method in my entity, if I also have to call the ->setOwner method on said Object. Only calling the ->setOwner is enough to add it to the collection, but adding it to the collection is not enough to have its owner set and this is counter-intuitive.

If I call $item->setContainer($container);, $item is automatically added to $container->items (after rehydrating $container); But calling $container->addItem($item); will not set $item->container to $container, which causes $container->items to be empty after a $entityManager->flush(); This is highly inconsistent, since $item->setContainer($container); adds the item to $container->items after I rehydrate $container. Doctrine already knows the items inside the collection are the inverse side and the entity that holds the collection is the owning side. There is no reason not to set the inverse-owning relationship (therefore destroying the owning-inverse relationship after a flush).

Comment by Marco Pivetta [ 31/Jul/13 ]

Doctrine does not modify the state of your objects except for identifiers (during persistence) and hydration (when creating them).

Regardless of Doctrine, you SHOULD keep your object graph consistent.

Please take following example as a guideline: https://gist.github.com/3121916

Additionally, if you clear your object manager and then reload your objects, you will notice they will actually be correctly loaded.

Again, doctrine does NOT fix your object graph. It saves and loads valid state. It won't ever set the inverse side of any of your objects (ever) automagically.

Comment by Pedro Cordeiro [ 31/Jul/13 ]

Even though Doctrine won't fix the graph, it will load a fixed graph on the next hydration. If I call $item->setContainer($container), it will automagically add $item to $container->items, the next time I hydrate that entity. Only the opposite is not true: since adding $item to $container->items won't set $item->container, on the next reload my collection will be empty (even though I had added items before persisting/flushing).

Doctrine will empty my collections on the next reload, if the collection's items' references to the owner are not set (obviously). You claim this is intended (for Doctrine probably shouldn't be changing my object states), but I think (and many people on stackoverflow and on the groups seem to agree) this causes a lot of referential integrity issues. I just don't see why I'd ever call $container->addItem, if it still requires me to call $item->setContainer($container) – and calling $item->setContainer($container) alone would have the same effect (even though it would keep my currently loaded graph out-of-sync with the database, the graph would be correctly reloaded on the next page hit, which seems to almost always be the case). I also don't see the issue of having Doctrine update the container property on each item, if they were added to $container->items.

I already got that Doctrine won't do it. I'd love if you could ellaborate on why Doctrine shouldn't do it.

Thank you.

Comment by Marco Pivetta [ 31/Jul/13 ]

The point is that Doctrine ORM doesn't modify your objects. It's just a DB-based very complex serializer, if you want to see it that way.

Comment by Christophe Coevoet [ 01/Aug/13 ]

The doc explicitly says that Doctrine does not track changes on the inverse side. So if you want to save the relation, your object graph has to set the owning side. Tracking on both sides would be slower and would cause huge issues (what would happen if changes done on the owning side and the inverse side are incompatible ?)

The best way to make the change transparent to other parts of your project is to handle it in the adder:

class Container
{
    public method addItem(Item $item)
    {
        $item->setContainer($this);
        $this->items[] = $item;
    }
}




[DDC-2146] Detach and merge cascading not working properly Created: 15/Nov/12  Updated: 08/Sep/13  Resolved: 08/Sep/13

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.2.2, 2.3
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Nick Walke Assignee: Benjamin Eberlei
Resolution: Invalid Votes: 0
Labels: cascade, detach, merge


 Description   

The problem is described in detail here: http://stackoverflow.com/questions/13372305/doctrine-detaching-caching-and-merging

No one on IRC seems to know why this won't work. I was using 2.2.2, I've since updated to 2.3 and I'm still seeing the same issue.



 Comments   
Comment by Nick Walke [ 15/Nov/12 ]

This was a typo on my part. Disregard.





Generated at Fri Oct 31 18:46:41 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.