Git Product home page Git Product logo

Comments (14)

nikophil avatar nikophil commented on June 24, 2024 2

I've just created a PR to mitigate this problem (note: it won't work if the setter / adder uses fluent api, due to some restrictions in symfony/var-exporter).
It still might occur in some other edge cases, I've also added a not in the docs about it

#635

from foundry.

mmarton avatar mmarton commented on June 24, 2024 1

I'm having the same issue, with this (simplified):

public function testIssue1(): void
{
    $event = EventFactory::createOne();
    $event->setLocation(LocationFactory::createOne());
    $event->_save();
}
// Doctrine\ORM\ORMInvalidArgumentException: A new entity was found through the relationship 'App\Entity\Event#location'


public function testIssue2(): void
{
    $event = EventFactory::createOne();
    $event->_withoutAutoRefresh(function (Event $event): void {
        $event->setLocation(LocationFactory::createOne());
    });
    $event->_save();
}
// TypeError: Cannot assign null to property AppEntityEventProxy::$_autoRefresh of type bool

from foundry.

NeuralClone avatar NeuralClone commented on June 24, 2024 1

While don't know for sure if I've had the same issue as @fouteox, I have had the issue brought up by @mmarton. I fixed it by using _real(). For example:

$contact = ContactFactory::createOne([
    'firstName' => 'Alyson',
    'lastName' => 'Perkins',
    'mainEmail' => null,
    'mainPhone' => null,
])

$accountContact = AccountContactFactory::createOne([
    'contact' => $contact,
    'account' => AccountFactory::new([
        'name' => 'Rhode Island',
        'uid' => 'RI',
    ]),
    'main' => true,
]);

$contact->addAccountContact($accountContact->_real());

// this blows up with the Doctrine error without calling _real() above
$contact->_save();

from foundry.

fouteox avatar fouteox commented on June 24, 2024

More details :

Work :

$post = PostFactory::createOne();

CommentFactory::createOne([
    'post' => $post,
]);

$this->browser()
            ->get(sprintf('/api/post/%s', $post->getId()))
            ->assertStatus(200)
        ;

Work :

$post = PostFactory::createOne();

CommentFactory::createOne([
    'post' => $post,
]);

$comment->setContent('content');
$comment->_save();

The error seems to come from calling via browser by sending $post THEN wanting to modify $comment, but why?

from foundry.

nikophil avatar nikophil commented on June 24, 2024

Hi,

do you modify the post in your functional test with browser?

from foundry.

nikophil avatar nikophil commented on June 24, 2024

what happens if you do this?

$comment->_withoutAutoRefresh(function (Post $post) {
    $comment->setContent('content');
});
$comment->_save();

from foundry.

fouteox avatar fouteox commented on June 24, 2024

No, and this work too :

$comment = CommentFactory::createOne(['post' => PostFactory::createOne()]);

$this->browser()
            ->get(sprintf('/api/post/%s', $comment->getPost()->getId()))
            ->assertStatus(200)
        ;

$comment->setContent('content');
$comment->_save();

from foundry.

nikophil avatar nikophil commented on June 24, 2024

I don't get the difference between the last working version and the failing one?

from foundry.

fouteox avatar fouteox commented on June 24, 2024

what happens if you do this?

$comment->_withoutAutoRefresh(function (Post $post) {
    $comment->setContent('content');
});
$comment->_save();

I have this error :

TypeError: Value of type null returned from AppEntityCommentProxy::__get() must be compatible with unset property AppEntityCommentProxy::$_autoRefresh of type bool

I don't get the difference between the last working version and the failing one?

The only difference between the code that works and the code that doesn't is that I declare post directly in the comment.

If I instantiate it in a variable it fails.

Don't work :

$post = PostFactory::createOne();

$comment = CommentFactory::createOne(['post' => $post]);

$this->browser()
            ->get(sprintf('/api/post/%s', $post->getId()))
            ->assertStatus(200)
        ;

$comment->setContent('content');
$comment->_save();

Work :

$comment = CommentFactory::createOne(['post' => PostFactory::createOne()]);

$this->browser()
            ->get(sprintf('/api/post/%s', $comment->getPost()->getId()))
            ->assertStatus(200)
        ;

$comment->setContent('content');
$comment->_save();

Je viens de voir que tu étais français donc je décris mon problème dans cette langue, je pense que je serai mieux compris.

En fait j'ai l'impression que d'extraire "comment" dans une variable, ce qui en fait donc un proxy, pose problème avec browser pour une raison que j'ignore.

Ce qui est étrange, c'est qu'il y a plusieurs scénarios qui fonctionnent, mais un en particulier pose soucis.
C'est quand je créé un "comment" dans une variable, l'affecte ensuite à "post", puis execute un appel à browser. Dans ce cas là, si j'essaie de modifier "comment", l'erreur se produit.

Encore une fois, si je n'extrais pas "comment" dans une variable, je n'ai aucune erreur.

from foundry.

fouteox avatar fouteox commented on June 24, 2024

Also works when we access $comment in browser via $post->getComment()->getId() :

$post = PostFactory::createOne();

$comment = CommentFactory::createOne(['post' => $post]);

$this->browser()
            ->get(sprintf('/api/post/%s', $comment->getPost()->getId()))
            ->assertStatus(200)
        ;

$comment->setContent('content');
$comment->_save();

from foundry.

nikophil avatar nikophil commented on June 24, 2024

Hi @mmarton

I'm wondering if both problems are the same... Could you give me the whole error message, please? (from your first example)
I think your problem will be solved by passing LocationFactory::createOne()->_real()

We're gonna advertise on the docs for this problem

from foundry.

mmarton avatar mmarton commented on June 24, 2024

Sure, here is the full stack:

Foundry (Tests\Integration\Foundry)
 ✘ Orm issue
   ┐
   ├ Doctrine\ORM\ORMInvalidArgumentException: A new entity was found through the relationship 'App\Entity\Event#location' that was not configured to cascade persist operations for entity: Rutherford Group. 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"}).
   │
   │ /var/www/html/vendor/doctrine/orm/src/ORMInvalidArgumentException.php:103
   │ /var/www/html/vendor/doctrine/orm/src/UnitOfWork.php:3859
   │ /var/www/html/vendor/doctrine/orm/src/UnitOfWork.php:417
   │ /var/www/html/vendor/doctrine/orm/src/EntityManager.php:403
   │ /var/www/html/vendor/zenstruck/foundry/src/Persistence/PersistenceManager.php:197
   │ /var/www/html/vendor/zenstruck/foundry/src/Persistence/PersistenceManager.php:171
   │ /var/www/html/vendor/zenstruck/foundry/src/Persistence/IsProxy.php:60
   │ /var/www/html/tests/Integration/FoundryTest.php:22
   ┴

from foundry.

fouteox avatar fouteox commented on June 24, 2024

I've just created a PR to mitigate this problem (note: it won't work if the setter / adder uses fluent api, due to some restrictions in symfony/var-exporter). It still might occur in some other edge cases, I've also added a not in the docs about it

#635

Yes I can confirm that the code below works. That is to say by having a setter which returns not static but void. But is it that we need to double setter for the tests to work?

$post = PostFactory::createOne();

$comment = CommentFactory::createOne(['post' => $post]);

$this->browser()
            ->get(sprintf('/api/post/%s', $post->getId()))
            ->assertStatus(200)
        ;

$comment->setContentWithoutStatic('content'); // Here, setter return void instead static
$comment->_save();

from foundry.

nikophil avatar nikophil commented on June 24, 2024

Creating new public methods specific for the tests is definitely not what you need to do 😅
maybe you could try:

$comment->_real()->setContent('content');

or maybe try another time _withoutAutoRefresh(), we've fixed the problem in v2.0.2

$comment->_withoutAutoRefresh(function (Post $post) {
    $comment->setContent('content');
});
$comment->_save();

side note: I must say I still don't understand why a functional test here would create an error. If you manage to create a reproducer project, I'd be happy to debug that.

from foundry.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.