Ticket #280 (closed task: fixed)
Add identity map to ensure unique object instances
| Reported by: | hans | Owned by: | hans |
|---|---|---|---|
| Priority: | normal | Milestone: | 1.3 |
| Component: | Generator | Version: | devel |
| Severity: | normal | Keywords: | |
| Cc: | oliver@… |
Description (last modified by hans) (diff)
See Oliver's good discussion of this issue at wiki:Development/UniqueInstances
Also see #187 for an example implementation of the needed getPrimaryKeyHash() method.
Although Oliver's patches were for the Propel 1.2 branch, the basic internals of Propel object hydration are basically the same in 2.0 -- and hence the implementation he suggests on the wiki is almost completely what we need.
Here is a distilled list of requirements for this task:
- Add getPrimaryKeyHash($row, $startcol) to the Peer classes.
- Add an $instances array to the Peer classes.
- Note: I think it makes sense to keep this in the Peer classes because the Peer classes provide a natural way to categorize the classes. In particular, there could be issues with correctly categorizing instances of inherited classes. We do have to make these $instances maps public, however.
- Add logic to the retrieveByPK(), populateObjects(), and doSelectJoin*() methods to first check whether the instance was loaded before hydrating the object.
- Note: I don't think it's worth bothering with a new version of retrieveByPKs() because that method just calls doSelect() which is going to pull objects from the identity map if they already exist.
- Finally, we should be able to simplify much of the kludgy code in Propel 1.2 that exists to prevent duplicate object instances in object trees, etc.
Also, for the implementation of getPrimaryKeyHash(), I think it makes sense to use serialize() instead of implode() for the multi-column primary key. Using serialize() is marginally slower, but it prevents problems in the case where a primary key might actually have '.' characters in it (this is not completely out of the question, as, for example, the node classes use '.' to delimit tree paths).
