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

Make it possible to have non-NULLable self-referencing associations when using application-provided IDs #10735

Conversation

mpdude
Copy link
Contributor

@mpdude mpdude commented Jun 1, 2023

This change improves scheduling of extra updates in the BasicEntityPersister.

Extra updates can be avoided when

  • the referred-to entity has already been inserted during the current insert batch/transaction and the post-insert (database) ID is already available in the entity
  • we have a self-referencing entity with application-provided ID values (the NONE generator strategy).

As a corollary, with this change applications that provide their own IDs can define self-referencing associations as not NULLable.

One caveat, though: In the absence of entity-level commit ordering (#10547), it is not guaranteed that entities with self-references (at the class level) will be inserted in a suitable order. The order depends on the sequence in which the entities were added with persist().

Fixes #7877, closes #7882.

Co-authored-by: Sylvain Fabre [email protected]

@mpdude mpdude force-pushed the nullable-self-reference-application-provided-id branch from 96ce115 to b0d8fec Compare June 1, 2023 06:42
@mpdude mpdude mentioned this pull request Jun 1, 2023
@mpdude mpdude force-pushed the nullable-self-reference-application-provided-id branch 2 times, most recently from 7870752 to 592fe57 Compare June 2, 2023 06:40
@mpdude
Copy link
Contributor Author

mpdude commented Jun 2, 2023

We need to process the post-insert IDs earlier: Not after executeInserts() has been finished, but rather during the execution. → #10743

@mpdude mpdude force-pushed the nullable-self-reference-application-provided-id branch 2 times, most recently from dc62bb6 to 520a6f4 Compare June 2, 2023 09:29
@mpdude mpdude marked this pull request as draft June 2, 2023 09:39
@mpdude mpdude force-pushed the nullable-self-reference-application-provided-id branch from 520a6f4 to 82a2ed6 Compare June 2, 2023 12:28
@mpdude mpdude changed the base branch from 2.15.x to 2.16.x June 2, 2023 12:28
mpdude added a commit to mpdude/doctrine2 that referenced this pull request Jun 21, 2023
This refactoring does two things:

* We can avoid collecting the post insert IDs in a cumbersome array structure that will be returned by the EntityPersisters and processed by the UoW right after. Instead, use a more expressive API: Make the EntityPersisters tell the UoW about the IDs immediately.
* IDs will be available in inserted entities a tad sooner. That may help to resolve doctrine#10735, where we can use the IDs to skip extra updates.
mpdude added a commit to mpdude/doctrine2 that referenced this pull request Jun 21, 2023
This refactoring does two things:

* We can avoid collecting the post insert IDs in a cumbersome array structure that will be returned by the EntityPersisters and processed by the UoW right after. Instead, use a more expressive API: Make the EntityPersisters tell the UoW about the IDs immediately.
* IDs will be available in inserted entities a tad sooner. That may help to resolve doctrine#10735, where we can use the IDs to skip extra updates.
mpdude added a commit to mpdude/doctrine2 that referenced this pull request Jun 21, 2023
This refactoring does two things:

* We can avoid collecting the post insert IDs in a cumbersome array structure that will be returned by the EntityPersisters and processed by the UoW right after. Instead, use a more expressive API: Make the EntityPersisters tell the UoW about the IDs immediately.
* IDs will be available in inserted entities a tad sooner. That may help to resolve doctrine#10735, where we can use the IDs to skip extra updates.
mpdude added a commit to mpdude/doctrine2 that referenced this pull request Jun 21, 2023
This refactoring does two things:

* We can avoid collecting the post insert IDs in a cumbersome array structure that will be returned by the EntityPersisters and processed by the UoW right after. Instead, use a more expressive API: Make the EntityPersisters tell the UoW about the IDs immediately.
* IDs will be available in inserted entities a tad sooner. That may help to resolve doctrine#10735, where we can use the IDs to skip extra updates.
mpdude added a commit to mpdude/doctrine2 that referenced this pull request Jun 21, 2023
This refactoring does two things:

* We can avoid collecting the post insert IDs in a cumbersome array structure that will be returned by the EntityPersisters and processed by the UoW right after. Instead, use a more expressive API: Make the EntityPersisters tell the UoW about the IDs immediately.
* IDs will be available in inserted entities a tad sooner. That may help to resolve doctrine#10735, where we can use the IDs to skip extra updates.
mpdude added a commit to mpdude/doctrine2 that referenced this pull request Jun 23, 2023
This refactoring does two things:

* We can avoid collecting the post insert IDs in a cumbersome array structure that will be returned by the EntityPersisters and processed by the UoW right after. Instead, use a more expressive API: Make the EntityPersisters tell the UoW about the IDs immediately.
* IDs will be available in inserted entities a tad sooner. That may help to resolve doctrine#10735, where we can use the IDs to skip extra updates.
…hen using application-provided IDs

This change improves scheduling of extra updates in the `BasicEntityPersister`.

Extra updates can be avoided when
* the referred-to entity has already been inserted during the current insert batch/transaction
* we have a self-referencing entity with application-provided ID values (the `NONE` generator strategy).

As a corollary, with this change applications that provide their own IDs can define self-referencing associations as not NULLable.

I am considering this a bugfix since the ORM previously executed additional queries that were not strictly necessary, and that required users to work with NULLable columns where conceptually a non-NULLable column would be valid and more expressive.

One caveat, though:

In the absence of entity-level commit ordering (doctrine#10547), it is not guaranteed that entities with self-references (at the class level) will be inserted in a suitable order. The order depends on the sequence in which the entities were added with `persist()`.

Fixes doctrine#7877, closes doctrine#7882.

Co-authored-by: Sylvain Fabre <[email protected]>
@mpdude mpdude force-pushed the nullable-self-reference-application-provided-id branch from 82a2ed6 to de85359 Compare July 7, 2023 11:41
@mpdude mpdude marked this pull request as ready for review July 7, 2023 11:42
@derrabus derrabus added this to the 2.16.0 milestone Jul 8, 2023
@derrabus derrabus merged commit efc83bc into doctrine:2.16.x Jul 8, 2023
@mpdude mpdude deleted the nullable-self-reference-application-provided-id branch July 8, 2023 14:01
@sylfabre
Copy link
Contributor

Thanks a lot @mpdude 💪

@mpdude
Copy link
Contributor Author

mpdude commented Jul 10, 2023

@sylfabre could you please close #7882 and #7877 when this change here solved the issue?

Thanks!

mpdude added a commit to mpdude/doctrine2 that referenced this pull request Aug 1, 2023
…cation-provided IDs

This excludes such associations from the commit order computation, since the foreign key constraint will be satisfied when inserting the row.

See doctrine#10735 for more details about this edge case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extra update for self-referencing Many-To-One with NONE generator strategy during persist
3 participants