-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Compute entity-level commit order for entity insertions #10689
Compute entity-level commit order for entity insertions #10689
Conversation
e007a7a
to
2723132
Compare
// According to https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/annotations-reference.html#annref_joincolumn, | ||
// the default for "nullable" is true. Unfortunately, it seems this default is not applied at the metadata driver, factory or other | ||
// level, but in fact we may have an undefined 'nullable' key here, so we must assume that default here as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, join columns are nullable by default for one-to-many relations and not nullable for many-to-many relations. If at this point you need to know these defaults, maybe ClassMetadata
should amend the nullable
key if it's missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have similar code here...
orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php
Lines 2079 to 2083 in 70477d8
foreach ($joinColumns as $joinColumn) { | |
if (! isset($joinColumn['nullable']) || $joinColumn['nullable']) { | |
return 'LEFT JOIN'; | |
} | |
} |
... or here ...
orm/lib/Doctrine/ORM/Tools/EntityGenerator.php
Lines 1260 to 1264 in 70477d8
foreach ($joinColumns as $joinColumn) { | |
if (isset($joinColumn['nullable']) && ! $joinColumn['nullable']) { | |
return false; | |
} | |
} |
... and for fields in general (not only join columns) for example here:
return $mapping !== false && isset($mapping['nullable']) && $mapping['nullable']; |
I agree that it would be better if the nullable
(and possibly other keys in those join column definition or field mapping configuration arrays) were initialized with defaults in the CMF; but that's out of scope here, so can we leave it for another PR?
tests/Doctrine/Tests/Models/PersistentObject/PersistentEntity.php
Outdated
Show resolved
Hide resolved
3394356
to
38f3faf
Compare
tests/Doctrine/Tests/ORM/Functional/OneToOneSelfReferentialAssociationTest.php
Show resolved
Hide resolved
This is the third step to break doctrine#10547 into smaller PRs suitable for reviewing. It uses the new topological sort implementation from doctrine#10592 and the refactoring from doctrine#10651 to compute the UoW's commit order for entity insertions not on the entity class level, but for single entities and their actual dependencies instead. #### Current situation `UnitOfWork::getCommitOrder()` would compute the entity sequence on the class level with the following code: https://github.com/doctrine/orm/blob/70477d81e96c0044ad6fd8c13c37b2270d082792/lib/Doctrine/ORM/UnitOfWork.php#L1310-L1325 #### Suggested change * Instead of considering the classes of all entities that need to be inserted, updated or deleted, consider the new (inserted) entities only. We only need to find a sequence in situations where there are foreign key relationships between two _new_ entities. * In the dependency graph, add edges for all to-one association target entities. * Make edges "optional" when the association is nullable. #### Test changes I have not tried to fully understand the few changes necessary to fix the tests. My guess is that those are edge cases where the insert order changed and we need to consider this during clean-up. Keep in mind that many of the functional tests we have assume that entities have IDs assigned in the order that they were added to the EntityManager. That does not change – so the order of entities is generally stable, equal to the previous implementation.
38f3faf
to
d76fc4e
Compare
2e02bbd
to
aa27b3a
Compare
Rebased and resolved conflicts after #10566 has been merged. I wanted to spare clean-ups (remove the now unused |
* | ||
* @return list<ClassMetadata> | ||
*/ | ||
private function getCommitOrder(): array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As of this PR, this method is no longer used.
I think this is the last PR regarding changes in implementation. Once we've got this merged, I can start making PRs to pick/collect/provide (regression) tests for all the fixed issues. That means the hard work would be done, hopefully reviewing tests added is easy :-) |
@greg0ire could you 👀 please? 🙏🏻 |
Please merge this, so I can continue with more tests on the |
Make the UoW find a commit order for entity insertions not on the class, but at the entity level. This is the third step to break #10547 into smaller PRs suitable for reviewing. It uses the new topological sort implementation from #10592 and the refactoring from #10651.
Current situation
UnitOfWork::getCommitOrder()
would compute the entity sequence on the class level with the following code:orm/lib/Doctrine/ORM/UnitOfWork.php
Lines 1310 to 1325 in 70477d8
Suggested change
Extra bonus
This is what the DALL·E AI thinks it looks like when the
UnitOfWork
is scheduling the sequence of entity insertions.