mirror of
https://github.com/doctrine/orm.git
synced 2026-03-23 22:42:18 +01:00
DDC-1306: Possible bug in CommitOrderCalculator #1642
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @doctrinebot on GitHub (Jul 30, 2011).
Originally assigned to: @beberlei on GitHub.
Jira issue originally created by user arthens:
(I'm not sure it's a bug, it might be the way I configured Doctrine)
Sometime Doctrine fails to calculate the right commit order, and then it fails when flushing because some db constraints are failing. I hacked the CommitOrderCalculator so that it would print the list of the dependencies, and this is what I found:
(I don't have time to write code now, so I'll try to explain it with words. If it's not clear I'll find some time tomorrow to hack together a test)
Let's say that we have the class User. The class user is connected to other classes (News, Comment, Post) with an unidirectional relation, so that User doesn't know anything about the other class.
Let's say we create a User and we save it. The CommitOrderCalculator will calculate the dependencies on User. This is a partial list, some dependencies won't be there (not sure whether it's because they haven't been loaded yet, whether it's because they are not part of the UnitOfWork or whether it's because User doesn't know about them) *****
Let's say that later, in the same request, we create a News. CommitOrderCalculator will calculate the dependencies for News. However, for User it will use the cached dependencies, and it won't realize that now User is required for News.
***** Could it be a configuration problem?
Are the dependencies supposed to be incomplete? (it seems reasonable as long as they are calculated for a single UnitOfWork, but it seems wrong if the dependencies are shared with multiple transactions)
Or am I loading the classes in the wrong way?
Code references:
UnitOfWork::getCommitOrder line 840
The class is added to $newNodes (the array used to calculate dependencies) only if the CommitOrderCalculator doesn't know the class already
CommitOrderCalculator::getCommitOrder line 83
After getting the order *sorted and _nodeStates are reset, while _classes and *relatedClasses are not.
Basically UnitOfWork register the class only once, and CommitOrderCalculator doesn't forget about the class when the UnitOfWork ends.
Possible fix:
Example:
Dependencies calculated with the current code
Visiting Users\Model\User
Forum\Model\Forum
Visiting Forum\Model\Forum
Forum\Model\Forum
Forum\Model\Topic
Visiting Forum\Model\Topic
Forum\Model\Topic
Forum\Model\Topic
Visiting Forum\Model\Post
Forum\Model\Forum
Forum\Model\Topic
Forum\Model\Topic
Dependencies calculated with the reset
Visiting Forum\Model\Topic
Forum\Model\Post
Visiting Forum\Model\Post
Forum\Model\Topic
Forum\Model\Topic
Forum\Model\Forum
Visiting Forum\Model\Forum
Forum\Model\Topic
Forum\Model\Forum
Visiting Users\Model\User
Forum\Model\Topic
Forum\Model\Topic
Forum\Model\Post
Forum\Model\Post
@doctrinebot commented on GitHub (Aug 6, 2011):
Comment created by @beberlei:
Verified.
The Calculator is only populated partially because otherwise it had to calculate the dependencies for all classes all the time, caused through a riffle effect.
@doctrinebot commented on GitHub (Aug 27, 2011):
Comment created by @beberlei:
Fixed
@doctrinebot commented on GitHub (Aug 27, 2011):
Issue was closed with resolution "Fixed"