ScheduledForDirtyCheck array is not cleared on commit. #4985

Closed
opened 2026-01-22 14:55:41 +01:00 by admin · 3 comments
Owner

Originally created by @SamirBoulil on GitHub (Jan 22, 2016).

Hello,

I'm experiencing some issues when using the EntityManager and UnitOfWork classes. When flush() is called on the EntityManager the commit() function is called on the unitOfWork object.

When the function returns at line 350, I still have objects living in the scheduledForDirtyCheck array which are not cleared unlike at the end of the function. (see code below)

Some information:

  • The entity is defined with "DEFERRED_EXPLICIT" and is loaded from the database via find. There are no changes made (or with the same value) to these objects.
  • When we call persist() on these objets they get added to the scheduledForDirtyCheck collection by this function.
  • When we call flush() on the entityManager we got an early return of the commit as Doctrine hasn't detected any modification which does not clear the scheduledForDirtyCheck array. (see code below)

The problem is that the collection keeps growing as we are processing more and more entities.

# Doctrine/ORM/UnitOfWork  
  public function commit($entity = null)
    {

        ....

        if ( ! ($this->entityInsertions ||
                $this->entityDeletions ||
                $this->entityUpdates ||
                $this->collectionUpdates ||
                $this->collectionDeletions ||
                $this->orphanRemovals)) {
            $this->dispatchOnFlushEvent();
            $this->dispatchPostFlushEvent();
            return; // Nothing to do. <-- scheduledForDirtyCheck array not cleared
        }

        ...

        $this->dispatchPostFlushEvent();

        // Clear up
        $this->entityInsertions =
        $this->entityUpdates =
        $this->entityDeletions =
        $this->extraUpdates =
        $this->entityChangeSets =
        $this->collectionUpdates =
        $this->collectionDeletions =
        $this->visitedCollections =
        $this->scheduledForDirtyCheck = // <- Array cleared
        $this->orphanRemovals = array();
    }

I wanted to know if I there could be a misuse from our part of the library ? How do you get this scheduledForDirtyCheck array cleared on commit ?

Regards,
Samir Boulil

Originally created by @SamirBoulil on GitHub (Jan 22, 2016). Hello, I'm experiencing some issues when using the EntityManager and UnitOfWork classes. When `flush()` is called on the EntityManager the `commit()` function is called on the unitOfWork object. When the function returns at line 350, I still have objects living in the `scheduledForDirtyCheck` array which are not cleared unlike at the end of the function. (see code below) Some information: - The entity is defined with `"DEFERRED_EXPLICIT"` and is loaded from the database via find. There are no changes made (or with the same value) to these objects. - When we call `persist()` on these objets they get added to the `scheduledForDirtyCheck` collection by this function. - When we call `flush()` on the entityManager we got an early return of the commit as Doctrine hasn't detected any modification which does not clear the `scheduledForDirtyCheck` array. (see code below) The problem is that the collection keeps growing as we are processing more and more entities. ``` php # Doctrine/ORM/UnitOfWork public function commit($entity = null) { .... if ( ! ($this->entityInsertions || $this->entityDeletions || $this->entityUpdates || $this->collectionUpdates || $this->collectionDeletions || $this->orphanRemovals)) { $this->dispatchOnFlushEvent(); $this->dispatchPostFlushEvent(); return; // Nothing to do. <-- scheduledForDirtyCheck array not cleared } ... $this->dispatchPostFlushEvent(); // Clear up $this->entityInsertions = $this->entityUpdates = $this->entityDeletions = $this->extraUpdates = $this->entityChangeSets = $this->collectionUpdates = $this->collectionDeletions = $this->visitedCollections = $this->scheduledForDirtyCheck = // <- Array cleared $this->orphanRemovals = array(); } ``` I wanted to know if I there could be a misuse from our part of the library ? How do you get this `scheduledForDirtyCheck` array cleared on commit ? Regards, Samir Boulil
admin added the Bug label 2026-01-22 14:55:41 +01:00
admin closed this issue 2026-01-22 14:55:43 +01:00
Author
Owner

@backbone87 commented on GitHub (Jan 26, 2016):

While the problem and its solution is clear, you must ask yourself, why do you call persist on a managed entity? You do that, because you know that you use DEFERRED_EXPLICIT and that you have changes in the entity that you want to sync with the DB, so you must call it. So the UoW commit expects changes in the entity, but could not find any. Maybe there will be changes in a later call to flush? It is a design decision of the library what the correct behavior should be. But when the current behavior is not the intented one, it must be considered that a behavior change could break legacy code easily, because of "forgotten dirty checks" between flushes.

@backbone87 commented on GitHub (Jan 26, 2016): While the problem and its solution is clear, you must ask yourself, why do you call persist on a managed entity? You do that, because you know that you use DEFERRED_EXPLICIT and that you have changes in the entity that you want to sync with the DB, so you must call it. So the UoW commit expects changes in the entity, but could not find any. Maybe there will be changes in a later call to flush? It is a design decision of the library what the correct behavior should be. But when the current behavior is not the intented one, it must be considered that a behavior change could break legacy code easily, because of "forgotten dirty checks" between flushes.
Author
Owner

@SamirBoulil commented on GitHub (Jan 27, 2016):

Hello, Thanks for the reply !

I understand that in some cases you might not want to clear this array on flush. It may happen that you called persist on an entity to tell doctrine it will be updated in the future and that you might not want it to be deleted from the unit of work right now.

However, if this entity is not cleared on flush, shouldn't it be cleaned from the $scheduledForDirtyCheck array when we call detach() on it ? Because it does not appear to be the case.

What do you think ?

@SamirBoulil commented on GitHub (Jan 27, 2016): Hello, Thanks for the reply ! I understand that in some cases you might not want to clear this array on flush. It may happen that you called persist on an entity to tell doctrine it will be updated in the future and that you might not want it to be deleted from the unit of work right now. However, if this entity is not cleared on flush, shouldn't it be cleaned from the $scheduledForDirtyCheck array when we call `detach()` on it ? Because it does not appear to be the case. What do you think ?
Author
Owner

@backbone87 commented on GitHub (Jan 27, 2016):

Like i already said are these behaviors all intentional or unintentional design decisions by the developers (i am not one of them). There is no right or wrong.

I agree with you on the detach, but that was never mentioned in your opening post.

@backbone87 commented on GitHub (Jan 27, 2016): Like i already said are these behaviors all intentional or unintentional design decisions by the developers (i am not one of them). There is no right or wrong. I agree with you on the `detach`, but that was never mentioned in your opening post.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#4985