DDC-1896: spl_object_hash collisions confuse Doctrine #2391

Closed
opened 2026-01-22 13:51:28 +01:00 by admin · 3 comments
Owner

Originally created by @doctrinebot on GitHub (Jun 27, 2012).

Originally assigned to: @beberlei on GitHub.

Jira issue originally created by user tporter:

Hello,

I'm trying to get some clarification on http://www.doctrine-project.org/jira/browse/DDC-136 .

If I create an object in a limited scope and then persistflush that object it should get saved into the storage engine. If the code execution leaves that scope the object gets destroyed by PHP garbage collection. Consequently, another new object can share the same spl_object_hash, if that new object is persistedflushed then this can cause issues with Doctrine, assuming that the same instance of Doctrine is available in both scopes (in this case, via Symfony2 service container).

It would seem that this is caused because $this->documentStates in UnitOfWork.php does not (and could not) get updated when the first object is destroyed by garbage collection. That array maintains the object state of the previous object that shared the same hash, thus the wrong queries get executed against the storage engine when a second object with the same hash is processed.

Are you saying that this is the correct behavior?

DDC-136 suggests that detach() should be called for each object just before it goes out of scope, this does seem to fix the issue. However, it doesn't seem to be documented. I don't see how a user could otherwise be expected to know about this behavior, the description at http://doctrine-orm.readthedocs.org/en/2.0.x/reference/working-with-objects.html#detaching-entities gives no explanation of why detach() should be called, merely the effects of doing so which do not make it clear that it is ever necessary.

Personally I feel that spl_object_hash() is an inappropriate mechanism to use for this, however in the absence of any better suggestion it would be nice if the documentation reflected some of the quirks that should be expected.

Kind regards,

Tim.

Originally created by @doctrinebot on GitHub (Jun 27, 2012). Originally assigned to: @beberlei on GitHub. Jira issue originally created by user tporter: Hello, I'm trying to get some clarification on http://www.doctrine-project.org/jira/browse/[DDC-136](http://www.doctrine-project.org/jira/browse/DDC-136) . If I create an object in a limited scope and then persist<ins>flush that object it should get saved into the storage engine. If the code execution leaves that scope the object gets destroyed by PHP garbage collection. Consequently, another new object can share the same spl_object_hash, if that new object is persisted</ins>flushed then this can cause issues with Doctrine, assuming that the same instance of Doctrine is available in both scopes (in this case, via Symfony2 service container). It would seem that this is caused because $this->documentStates in UnitOfWork.php does not (and could not) get updated when the first object is destroyed by garbage collection. That array maintains the object state of the previous object that shared the same hash, thus the wrong queries get executed against the storage engine when a second object with the same hash is processed. Are you saying that this is the correct behavior? [DDC-136](http://www.doctrine-project.org/jira/browse/DDC-136) suggests that detach() should be called for each object just before it goes out of scope, this does seem to fix the issue. However, it doesn't seem to be documented. I don't see how a user could otherwise be expected to know about this behavior, the description at http://doctrine-orm.readthedocs.org/en/2.0.x/reference/working-with-objects.html#detaching-entities gives no explanation of why detach() should be called, merely the effects of doing so which do not make it clear that it is ever necessary. Personally I feel that spl_object_hash() is an inappropriate mechanism to use for this, however in the absence of any better suggestion it would be nice if the documentation reflected some of the quirks that should be expected. Kind regards, Tim.
admin added the Bug label 2026-01-22 13:51:28 +01:00
admin closed this issue 2026-01-22 13:51:29 +01:00
Author
Owner

@doctrinebot commented on GitHub (Jul 5, 2012):

Comment created by @beberlei:

persist() + flush() does not leave the object out of scope. Its managed afterwards and saved inside the UnitOfWork. Only if you detach() the object it can be garbage collected, and consequently this method makes sure to cleanup all the spl_object_hash referenecs.

The probem with SplObjectStorage is, that the amout of calls to $storage[$object]['metadata'] is much slower than reusing a once computed hash.

@doctrinebot commented on GitHub (Jul 5, 2012): Comment created by @beberlei: persist() + flush() does not leave the object out of scope. Its managed afterwards and saved inside the UnitOfWork. Only if you detach() the object it can be garbage collected, and consequently this method makes sure to cleanup all the spl_object_hash referenecs. The probem with SplObjectStorage is, that the amout of calls to $storage[$object]['metadata'] is much slower than reusing a once computed hash.
Author
Owner

@doctrinebot commented on GitHub (Jul 5, 2012):

Comment created by @beberlei:

Enough clarification? Otherwise reopen please.

@doctrinebot commented on GitHub (Jul 5, 2012): Comment created by @beberlei: Enough clarification? Otherwise reopen please.
Author
Owner

@doctrinebot commented on GitHub (Jul 5, 2012):

Issue was closed with resolution "Won't Fix"

@doctrinebot commented on GitHub (Jul 5, 2012): Issue was closed with resolution "Won't Fix"
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#2391