Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misleading ORMInvalidArgumentException after removal of referred entity of ManyToOne association with onDelete: 'CASCADE' #11539

Open
tobiasgv opened this issue Jul 2, 2024 · 2 comments

Comments

@tobiasgv
Copy link

tobiasgv commented Jul 2, 2024

Bug Report

Q A
BC Break no
Version 3.2.1

Summary

For a ManyToOne association where the owning side (class A) has the onDelete: 'CASCADE' option set: when a referred entity (of class B) is removed by the entity manager then a subsequent call to persist()+flush() causes a misleading ORMInvalidArgumentException:

Doctrine\ORM\ORMInvalidArgumentException: A new entity was found through the relationship 'A#b' that was not configured to cascade persist operations for entity: XXX. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}).

for managed entities of class A (which were cascade deleted by the DB), since the referenced entity of class B is mis-interpreted as a new entity.

How to reproduce


        #[ORM\JoinColumn(name: 'b_identifier', referencedColumnName: 'identifier', onDelete: 'CASCADE')]
        #[ORM\ManyToOne(targetEntity: B::class)]
        private ?B $b = null;

        $b = new B();
        $this->entityManger->persist($b);
        $this->entityManger->flush();

        $a = new A();
        $a->setB($b);
        $this->entityManger->persist($a);
        $this->entityManger->flush();

        $this->entityManger->remove($b);
        $this->entityManger->flush();

        $b2 = new B();
        $this->entityManger->persist($b2);
        $this->entityManger->flush(); // throws

Expected behavior

No exception should be thrown.

Workaround

Unsetting the referenced entity before flushing prevents the exception:
$a->setB(null);

@stof
Copy link
Member

stof commented Jul 4, 2024

The issue in your case is that $a still reference $b in your UnitOfWork.

onDelete: 'CASCADE' is about configuring the database-level cascading on the foreign key. This will lead to the row being deleted from the database in the a table, but the ORM still has $a in its UnitOfWork as it does not know about this removal.

If your schema relies on onDelete: 'CASCADE' (or onDelete: 'SET NULL'), you should be careful when you keep using the UnitOfWork after a flush. To be reliable, you would have to clear the UnitOfWork after a flush involving removals (as such flushes might have triggered an onDelete behavior)

@tobiasgv
Copy link
Author

tobiasgv commented Jul 8, 2024

Ok, thank you. I will clear the UnitOfWork after the removal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants