PersistentCollection::matching uses getters #6158

Open
opened 2026-01-22 15:27:56 +01:00 by admin · 1 comment
Owner

Originally created by @arnaud-lb on GitHub (Jan 21, 2019).

Bug Report

Q A
BC Break no
Version 2.x

Summary

PersistentCollection::matching may use getters to fetch field values. This enforces the implementation of getters for every property that may be referenced in a criteria, and forces the getters to return a scalar (it is not possible to return a value object, for example).

This is troublesome for multiple reasons:

  • The ORM should not make assumptions about getters (it never does so, except here).
  • When the collection is not fully loaded in memory, PersistentCollection::matching uses different strategy that doesn't have access to getters. As a result, a Criteria will have different behaviours depending on the state of the collection (loaded in memory or not). For example, if a Criteria references a field whose getter does not exist or returns a value object, matching() will not work as expected when the collection is loaded in memory.

Current behaviour

PersistentCollection::matching may or may not use getters during execution, depending on the state of the collection.

How to reproduce

class Board
{
    /** @var Collection */
    private $issues;

    public function openIssues(): array
    {
        return $this->issues->matching(
            Criteria::create()->where(Criteria::expr()->eq('issueState', 'open'));
        );
    } 
}

class Issue
{
    /** @var string */
    private $issueState;

    public function getIssueState(): IssueState
    {
        return new IssueState($this->issueState);
    }
}

class IssueState
{
    /** @var string */
    private $state;
}

In this code, Board::openIssues() will find open issues when the $issues collection is not initialised, and will silently fail to find open issues when the collection is initialised.

Expected behaviour

PersistentCollection::matching must have predictable behaviour. Its behaviour should not depend on whether the collection is initialised or not.

Originally created by @arnaud-lb on GitHub (Jan 21, 2019). ### Bug Report | Q | A |------------ | ------ | BC Break | no | Version | 2.x #### Summary `PersistentCollection::matching` may use getters to fetch field values. This enforces the implementation of getters for every property that may be referenced in a criteria, and forces the getters to return a scalar (it is not possible to return a value object, for example). This is troublesome for multiple reasons: - The ORM should not make assumptions about getters (it never does so, except here). - When the collection is not fully loaded in memory, `PersistentCollection::matching` uses different strategy that doesn't have access to getters. As a result, a `Criteria` will have different behaviours depending on the state of the collection (loaded in memory or not). For example, if a `Criteria` references a field whose getter does not exist or returns a value object, `matching()` will not work as expected when the collection is loaded in memory. #### Current behaviour `PersistentCollection::matching` may or may not use getters during execution, depending on the state of the collection. #### How to reproduce ``` class Board { /** @var Collection */ private $issues; public function openIssues(): array { return $this->issues->matching( Criteria::create()->where(Criteria::expr()->eq('issueState', 'open')); ); } } class Issue { /** @var string */ private $issueState; public function getIssueState(): IssueState { return new IssueState($this->issueState); } } class IssueState { /** @var string */ private $state; } ``` In this code, `Board::openIssues()` will find open issues when the `$issues` collection is not initialised, and will silently fail to find open issues when the collection is initialised. #### Expected behaviour `PersistentCollection::matching` must have predictable behaviour. Its behaviour should not depend on whether the collection is initialised or not.
admin added the ImprovementBC Break labels 2026-01-22 15:27:56 +01:00
Author
Owner

@Ocramius commented on GitHub (Jan 21, 2019):

Pretty much on board with this: the reliance on transparent getters is dangerous and un-productive.

The problem is that the ship already sailed here, so we can only change this behavior in a major version of the tools, and deprecate this behavior in doctrine/collections.

@Ocramius commented on GitHub (Jan 21, 2019): Pretty much on board with this: the reliance on transparent getters is dangerous and un-productive. The problem is that the ship already sailed here, so we can only change this behavior in a major version of the tools, and deprecate this behavior in `doctrine/collections`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6158