foundry icon indicating copy to clipboard operation
foundry copied to clipboard

Bug: doctrine identity problem when using `$this` in a method of proxified objects

Open KDederichs opened this issue 1 year ago • 5 comments

Hey,

I just updated to 2.2 from 1.38 and I found an issue where foundry doesn't correctly handle objects that are created by proxy objects.

Given that you have a class Foo:

class Foo
{

    #[OneToMany(mappedBy: 'foo', targetEntity: FooBar::class, cascade: ['persist', 'remove'], fetch: 'EAGER', orphanRemoval: true)]
    private Collection $fooBarCollection;

    public function addBarToFoo(Bar $bar): self 
    {
        $fooBar = new FooBar();
        $fooBar->setBar($bar)->setFoo($this);

        return $this.
    }

    public function createABarAndAddToFoo(): self 
    {
        $bar = new Bar():
        return $this->addBarToFoo($bar);
    }
}

class Bar
{
    //something
}

class FooBar {
    
    #[ManyToOne(targetEntity: Foo::class, inversedBy: 'fooBarCollection')]
    private Foo $foo;

    #[ManyToOne(targetEntity: Bar::class, cascade: ['persist'], fetch: 'EAGER')]  
    private Bar $bar;

    public function setFoo(Foo $foo): self
    {
        $this->foo = $foo;
    
        return $this;
    }

    public function setBar(Bar $bar): self
    {
        $this->bar = $bar;

        return $this;
    }
}

When you create a new Foo using FooFactory::createOne() and then call createABarAndAddToFoo() and _save() on the created Foo object this will result in an error like this:

Doctrine\ORM\ORMInvalidArgumentException: A new entity was found through the relationship 'App\Entity\FooBar#foo' 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"}).

This error obviously should happen since the Foo object has been created by the factory earlier and thus exists/is persisted. This was not an issue in the 1.x version of Foundry.

You can 'fix' it by prefixing the createABarAndAddToFoo call with a _real() but I'd rather have it work correctly :)

KDederichs avatar Oct 28 '24 10:10 KDederichs

Hello,

please, could you share your factories?

nikophil avatar Oct 29 '24 06:10 nikophil

https://github.com/KDederichs/sf-reproducer/tree/foundy/proxy_save here's a reproducer for that, just default factories as they come out of the box

KDederichs avatar Oct 29 '24 14:10 KDederichs

thank you for the reproducer, I'll soon check this!

nikophil avatar Oct 31 '24 06:10 nikophil

hye @KDederichs sorry for the late reply.

this problem gaves us headaches :exploding_head:

for now, this cannot be fixed in an other way than using ->_real() :shrug:

nikophil avatar Nov 22 '24 15:11 nikophil

Haha yeah it's a strange one for sure, I'll keep using _real() when I run into it for sure till you eventually figure it out :)

KDederichs avatar Nov 22 '24 23:11 KDederichs

I'm closing this, as there is no way to fix this with the current proxy mechanism

in a near future, proxy mechanism will be dropped from Foundry and replaced with the PHP 8.4 lazy proxy

see https://github.com/zenstruck/foundry/pull/943

nikophil avatar Jul 06 '25 17:07 nikophil