Closed yann-eugone closed 3 years ago
Thanks for the report @yann-eugone.
It's working in 3.77. Seems related to https://github.com/sonata-project/SonataAdminBundle/pull/6438
The CollectionType
by_reference => false
option is now passed to the AdminType.
We need to know if the collection type has by_reference
or not in order to call the right method addInstance/setObject
.
But it seems that changing the by_reference
option of the AdminType has other impact.
So it's maybe better to provide a collection_by_reference
option
https://github.com/sonata-project/SonataAdminBundle/pull/6565
Then a PR would be neede here: https://github.com/sonata-project/SonataDoctrineORMAdminBundle/blob/3.x/src/Builder/FormContractor.php#L227 To change to
$typeOptions['collection_by_reference'] = $formOptions['by_reference'];
I currently don't see another solution.
Thanks for this very quick answer @VincentLanglet :)
Looks like you were right : downgrading to 3.77
looks like a solution.
I tried to figure out which was the impacts of by_reference
option, and there is only 2 in Symfony :
Symfony\Component\Form\Form::setData
causing PersistentCollection to be duplicated : but this exists for years nowSymfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper::mapFormsToData
causing collection to be "replaced" on submit : and this exists for a while tooMaybe it is just me not undserstanding how this works, but it can't see what part of the code produced between 3.77.0 & 3.78.1 is messing the whole thing up...
Maybe it is just me not understanding how this works, but it can't see what part of the code produced between 3.77.0 & 3.78.1 is messing the whole thing up...
Since 3.78 we pass the CollectionType
options to persistence bundle.
See https://github.com/sonata-project/SonataAdminBundle/pull/6438/files#diff-9516ba91e79cc249e2c83431f248056fa195d97a4e3e533f6aab8657ef2ba093R134
And then, the persistence bundle send back type_options => ['by_reference' => $options['by_reference']]
See https://github.com/sonata-project/SonataDoctrineORMAdminBundle/blob/3.x/src/Builder/FormContractor.php#L227
And the bug occur because of
Symfony\Component\Form\Form::setData
causing PersistentCollection to be duplicated : but this exists for years now
Disclaimer : This is a really weird bug for which I had some bad time understanding why this is happening. Explanation might not be as clear as possible. But I'm fully available fore more information/demo.
Environment
Sonata packages
Symfony packages
PHP version
Subject
When you embed a collection of admin, using
CollectionType
& settingby_reference=false
option. All entries in collection are removed and re-created as new objects.Steps to reproduce
I've created a sample project, with minimal code/dependencies : https://github.com/yann-eugone/sonata-collection-error. In this project, I've added a
UniqueEntity
constraint onto Experience entity, in order to highlight the issue.If you create a
Person
entity, with 1Experience
, and if you press Update right after object creation you will have the following error :Expected results
Collection entries should be preserved.
Actual results
Collection entries are removed and re-created.
Further investigations
I've spent some time debugging why/where/when this is happening. Had some times in the property path classes, but not sure if this is the place to look. I tested this behavior in a Symfony only project, and this behavior is not reproduced. This is why i've opened this issue here.
I've also tried to downgrade my demo project to a lower version of sonata, but I also has to downgrade symfony : on the sonata highest version allowed with symfony 4.3, the issue is not reproduced either.