Wrong ORMInvalidArgumentException "A new entity was found through the relationship ..." #5171

Open
opened 2026-01-22 15:00:30 +01:00 by admin · 6 comments
Owner

Originally created by @insel-maz on GitHub (Jun 30, 2016).

Test provided here

An association entity (OrderLine) is added to both sides (ShopOrder#orderLines and Article#orderLines).

ShopOrder and OrderLine form an aggregate. ShopOrder is the aggregate root and therefore ShopOrder#orderLines cascades all operations. Article is not part of the aggregate and Article#orderLines is a simple collection without cascading.

Because the new OrderLine is added to Article#orderLines Doctrine throws a Doctrine\ORM\ORMInvalidArgumentException which should not occur because the same entity is also added to the second collection ShopOrder#orderLines.

Originally created by @insel-maz on GitHub (Jun 30, 2016). [Test provided here](https://github.com/insel-maz/doctrine2-bug-doctrine-bidirectional-association) An association entity (`OrderLine`) is added to both sides (`ShopOrder#orderLines` and `Article#orderLines`). `ShopOrder` and `OrderLine` form an aggregate. `ShopOrder` is the aggregate root and therefore `ShopOrder#orderLines` cascades all operations. `Article` is not part of the aggregate and `Article#orderLines` is a simple collection without cascading. Because the new `OrderLine` is added to `Article#orderLines` Doctrine throws a `Doctrine\ORM\ORMInvalidArgumentException` which should not occur because the same entity is also added to the second collection `ShopOrder#orderLines`.
admin added the BugInvalid labels 2026-01-22 15:00:30 +01:00
Author
Owner

@Ocramius commented on GitHub (Jul 5, 2016):

Because the new OrderLine is added to Article#orderLines Doctrine throws a Doctrine\ORM\ORMInvalidArgumentException which should not occur because the same entity is also added to the second collection ShopOrder#orderLines.

I just checked your example, and it seems like something is wrong on the consumer side: 7a2288d18a/index.php (L22)

Copying the code for reference:

?php
require_once "bootstrap.php";
echo 'Adding articles...', PHP_EOL;
$article1 = new Article("CPU");
$entityManager->persist($article1);
$article2 = new Article("RAM");
$entityManager->persist($article2);
$entityManager->flush();
echo 'Creating order with article...', PHP_EOL;
$shopOrder1 = new ShopOrder();
$shopOrder1->createOrderLine($article1);
$entityManager->persist($shopOrder1);
$entityManager->flush();
echo 'Adding some more articles...', PHP_EOL;
$shopOrder1->createOrderLine($article2);
$entityManager->flush();
echo 'End.', PHP_EOL;

You are not calling $entityManager->persist($shopOrder1), so the ORM doesn't perform any cascade persist operations on that side. Seems like expected behavior to me, at least...

@Ocramius commented on GitHub (Jul 5, 2016): > Because the new `OrderLine` is added to `Article#orderLines` Doctrine throws a `Doctrine\ORM\ORMInvalidArgumentException` which should not occur because the same entity is also added to the second collection `ShopOrder#orderLines`. I just checked your example, and it seems like something is wrong on the consumer side: https://github.com/insel-maz/doctrine2-bug-doctrine-bidirectional-association/blob/7a2288d18a06e89be486bfde55aa5761ce1ee4ba/index.php#L22 Copying the code for reference: ``` php ?php require_once "bootstrap.php"; echo 'Adding articles...', PHP_EOL; $article1 = new Article("CPU"); $entityManager->persist($article1); $article2 = new Article("RAM"); $entityManager->persist($article2); $entityManager->flush(); echo 'Creating order with article...', PHP_EOL; $shopOrder1 = new ShopOrder(); $shopOrder1->createOrderLine($article1); $entityManager->persist($shopOrder1); $entityManager->flush(); echo 'Adding some more articles...', PHP_EOL; $shopOrder1->createOrderLine($article2); $entityManager->flush(); echo 'End.', PHP_EOL; ``` You are not calling `$entityManager->persist($shopOrder1)`, so the ORM doesn't perform any cascade persist operations on that side. Seems like expected behavior to me, at least...
Author
Owner

@Ocramius commented on GitHub (Jul 5, 2016):

Tentatively marked as Invalid, although I'd first want to hear what the expected behavior would be here.

Also, can you try running a clear() and find() in between, and see if it works?

@Ocramius commented on GitHub (Jul 5, 2016): Tentatively marked as `Invalid`, although I'd first want to hear what the expected behavior would be here. Also, can you try running a `clear()` and `find()` in between, and see if it works?
Author
Owner

@insel-maz commented on GitHub (Jul 5, 2016):

In section 'Creating order with article...' there is a $entityManager->persist($shopOrder1). After this point the entity is managed and the UnitOfWork will check for changes for every further call to flush().
In the last section 'Adding some more articles...' the error occurs: A new OrderLine is created and added to two collections. Then while flushing it seems Article#orderLines is checked first. Doctrine prematurely throws an exception ignoring the second collection ShopOrder#orderLines with cascading enabled.

Clearing and finding the entities in the beginning of the last section results in the same error.

@insel-maz commented on GitHub (Jul 5, 2016): In section _'Creating order with article...'_ there is a `$entityManager->persist($shopOrder1)`. After this point the entity is managed and the UnitOfWork will check for changes for every further call to `flush()`. In the last section _'Adding some more articles...'_ the error occurs: A new `OrderLine` is created and added to two collections. Then while flushing it seems `Article#orderLines` is checked first. Doctrine prematurely throws an exception ignoring the second collection `ShopOrder#orderLines` with cascading enabled. Clearing and finding the entities in the beginning of the last section results in the same error.
Author
Owner

@DHager commented on GitHub (Nov 8, 2016):

@insel-maz Does the fix in PR #1521 solve your scenario?

@DHager commented on GitHub (Nov 8, 2016): @insel-maz Does the fix in PR #1521 solve your scenario?
Author
Owner

@insel-maz commented on GitHub (Nov 10, 2016):

@DHager Your updated UnitOfWork.php fixes the problem, thank you.

@insel-maz commented on GitHub (Nov 10, 2016): @DHager Your updated `UnitOfWork.php` fixes the problem, thank you.
Author
Owner

@teohhanhui commented on GitHub (Mar 30, 2017):

Got bitten by this too. My scenario is:

Payment -(cascade persists)-> PayAction
RedeemUserCreditsAction -> PayAction

@teohhanhui commented on GitHub (Mar 30, 2017): Got bitten by this too. My scenario is: Payment -(cascade persists)-> PayAction RedeemUserCreditsAction -> PayAction
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5171