EntityRepository.count don't handle Criteria array/object #5870

Closed
opened 2026-01-22 15:20:39 +01:00 by admin · 6 comments
Owner

Originally created by @Stoakes on GitHub (Feb 4, 2018).

Originally assigned to: @Ocramius on GitHub.

Hi

I'm trying to count several entities using EntityRepository.count() method. My criteria is quite complex so I use the Criteria class to express it. However it is not working. My tests let me think that there is an issue between the signature of EntityRepository.count and EntityPersister.count.

Use Case

I have an Office object. An office has a user (Many to One with User entity) and stands at a floor (integer).
I want to count all the Office belonging to a user and higher than a given floor.

Attempts

Based on the documentation I tried

<?php
$criteria = Criteria::create()
                ->where(Criteria::expr()->gte('floor', 2))
                ->andWhere(Criteria::expr()->eq('user', $user));
$count_office = $this->em->getRepository('Office')->count([$criteria]);

It gives me Unrecognized field: 0 full stack trace

Of course if I try without the array:

<?php
// ..
$count_office = $this->em->getRepository('Office')->count($criteria);

I get a Type error: Argument 1 passed to Doctrine\ORM\EntityRepository::count() must be of the type array, object given, called in /app/src/Service/OfficeService.php on line 189.

Workaround

My current workaround (and what makes me think it is a bug), is:

In my own OfficeRepository, add a countBis method which uses the EntityRepository.count implementation:

<?php
# OfficeRepository.php

use Doctrine\Common\Collections\Criteria;

class OfficeRepository extends EntityRepository {

   public function countBis(Criteria $criteria)
    {
        return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->count($criteria);
    }
}
<?php
# OfficeService.php

$criteria = Criteria::create()->where(Criteria::expr()->gte('floor', 2))
                ->andWhere(Criteria::expr()->eq('user', $user));
$count_agence = $this->em->getRepository('Office')->countBis($criteria);

Doctrine info

$ composer info

doctrine/annotations              v1.6.0             
doctrine/cache                    v1.7.1          
doctrine/collections              v1.5.0          
doctrine/common                   v2.8.1          
doctrine/data-fixtures            v1.3.0         
doctrine/dbal                     v2.6.3          
doctrine/doctrine-bundle          1.8.1           
doctrine/doctrine-cache-bundle    1.3.2              
doctrine/doctrine-fixtures-bundle 3.0.2             
doctrine/inflector                v1.2.0          
doctrine/instantiator             1.1.0             
doctrine/lexer                    v1.0.1            
doctrine/orm                      v2.6.0             

Thanks

Originally created by @Stoakes on GitHub (Feb 4, 2018). Originally assigned to: @Ocramius on GitHub. Hi I'm trying to count several entities using `EntityRepository.count()` method. My criteria is quite complex so I use the `Criteria` class to express it. However it is not working. My tests let me think that there is an issue between the signature of `EntityRepository.count` and `EntityPersister.count`. ## Use Case I have an `Office` object. An office has a `user` (Many to One with `User` entity) and stands at a floor (integer). I want to count all the `Office` belonging to a user and higher than a given floor. ## Attempts Based on the documentation I tried ```php <?php $criteria = Criteria::create() ->where(Criteria::expr()->gte('floor', 2)) ->andWhere(Criteria::expr()->eq('user', $user)); $count_office = $this->em->getRepository('Office')->count([$criteria]); ``` It gives me **Unrecognized field: 0** [full stack trace](https://gist.github.com/Stoakes/d6614d60b1c0b27e1e444cd07168a18c) Of course if I try without the array: ```php <?php // .. $count_office = $this->em->getRepository('Office')->count($criteria); ``` I get a `Type error: Argument 1 passed to Doctrine\ORM\EntityRepository::count() must be of the type array, object given, called in /app/src/Service/OfficeService.php on line 189`. ## Workaround My current workaround (and what makes me think it is a bug), is: In my own `OfficeRepository`, add a `countBis` method which uses the `EntityRepository.count` implementation: ```php <?php # OfficeRepository.php use Doctrine\Common\Collections\Criteria; class OfficeRepository extends EntityRepository { public function countBis(Criteria $criteria) { return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->count($criteria); } } ``` ```php <?php # OfficeService.php $criteria = Criteria::create()->where(Criteria::expr()->gte('floor', 2)) ->andWhere(Criteria::expr()->eq('user', $user)); $count_agence = $this->em->getRepository('Office')->countBis($criteria); ``` ## Doctrine info ```bash $ composer info doctrine/annotations v1.6.0 doctrine/cache v1.7.1 doctrine/collections v1.5.0 doctrine/common v2.8.1 doctrine/data-fixtures v1.3.0 doctrine/dbal v2.6.3 doctrine/doctrine-bundle 1.8.1 doctrine/doctrine-cache-bundle 1.3.2 doctrine/doctrine-fixtures-bundle 3.0.2 doctrine/inflector v1.2.0 doctrine/instantiator 1.1.0 doctrine/lexer v1.0.1 doctrine/orm v2.6.0 ``` Thanks
admin added the Question label 2026-01-22 15:20:39 +01:00
admin closed this issue 2026-01-22 15:20:40 +01:00
Author
Owner

@Ocramius commented on GitHub (Feb 5, 2018):

Is this bit in your example intentional?

->count([$criteria]);
@Ocramius commented on GitHub (Feb 5, 2018): Is this bit in your example intentional? ```php ->count([$criteria]); ```
Author
Owner

@Ocramius commented on GitHub (Feb 5, 2018):

Ah, I see what is wrong there. This is a naming mismatch in the API.

You probably want to use the Doctrine\Common\Collections\Selectable interface.

Usage is as follows:

$numberOfEntries = $entityRepository
    ->matching(
        Criteria::create()
            ->andWhere(Criteria::expr()->eq('foo', 'bar'))
    )
    ->count();

The name criteria (for parameters) is a restrictive criteria of key => value scalar values to restrict the search upon, and that's something we had since even before Doctrine\Common\Collections\Selectable was introduced.

@Ocramius commented on GitHub (Feb 5, 2018): Ah, I see what is wrong there. This is a naming mismatch in the API. You probably want to use the `Doctrine\Common\Collections\Selectable` interface. Usage is as follows: ```php $numberOfEntries = $entityRepository ->matching( Criteria::create() ->andWhere(Criteria::expr()->eq('foo', 'bar')) ) ->count(); ``` The name `criteria` (for parameters) is a restrictive criteria of `key => value` scalar values to restrict the search upon, and that's something we had since even before `Doctrine\Common\Collections\Selectable` was introduced.
Author
Owner

@holtkamp commented on GitHub (Feb 5, 2018):

The following links might be useful when encountering the limitations of Doctrine\Common\Collections\Selectable:

@holtkamp commented on GitHub (Feb 5, 2018): The following links might be useful when encountering the limitations of `Doctrine\Common\Collections\Selectable`: - http://mnapoli.fr/collection-interface-and-database-abstraction/ - https://github.com/rikbruil/Doctrine-Specification
Author
Owner

@Stoakes commented on GitHub (Feb 5, 2018):

Hi.

Thank you for your time. However, I think we misunderstood.

Let me try to reformulate.

Currently in Doctrine\ORM\EntityRepository, we have that piece of code (which accepts only array)

<?php
    /**
     * Counts entities by a set of criteria.
     *
     * @todo Add this method to `ObjectRepository` interface in the next major release
     *
     * @param array $criteria
     *
     * @return int The cardinality of the objects that match the given criteria.
     */
    public function count(array $criteria)
    {
        return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->count($criteria);
    }

The underlying implementation, described in Doctrine\ORM\Persisters\Entity\EntityPersister accepts a Criteria.

<?php
    /**
     * Count entities (optionally filtered by a criteria)
     *
     * @param  array|\Doctrine\Common\Collections\Criteria $criteria
     *
     * @return int
     */
    public function count($criteria = []);

The bug is that the array type constraint in EntityRepository.count just prevent me from using a Criteria. However, if I manually remove this constraint in the dependency code, passing a Criteria works fine.

My solution would be to just remove the type constraint, and everything would work fine.

Is my explanation now clearer ?

@Stoakes commented on GitHub (Feb 5, 2018): Hi. Thank you for your time. However, I think we misunderstood. Let me try to reformulate. Currently in `Doctrine\ORM\EntityRepository`, we have that piece of code (which accepts only array) ```php <?php /** * Counts entities by a set of criteria. * * @todo Add this method to `ObjectRepository` interface in the next major release * * @param array $criteria * * @return int The cardinality of the objects that match the given criteria. */ public function count(array $criteria) { return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->count($criteria); } ``` The underlying implementation, described in `Doctrine\ORM\Persisters\Entity\EntityPersister` accepts a `Criteria`. ```php <?php /** * Count entities (optionally filtered by a criteria) * * @param array|\Doctrine\Common\Collections\Criteria $criteria * * @return int */ public function count($criteria = []); ``` The bug is that the array type constraint in `EntityRepository.count` just prevent me from using a `Criteria`. However, if I manually remove this constraint in the dependency code, passing a `Criteria` works fine. My solution would be to just remove the type constraint, and everything would work fine. Is my explanation now clearer ?
Author
Owner

@Ocramius commented on GitHub (Feb 5, 2018):

Yes, that's clearer, but it won't be done. Please use the Selectable API
instead.

On 5 Feb 2018 20:09, "Antoine Beyet" notifications@github.com wrote:

Hi.

Thank you for your time. However, I think we misunderstood.

Let me try to reformulate.

Currently in Doctrine\ORM\EntityRepository, we have that piece of code
(which accepts only array)

<?php /** * Counts entities by a set of criteria. * * @todo Add this method to `ObjectRepository` interface in the next major release * * @param array $criteria * * @return int The cardinality of the objects that match the given criteria. */ public function count(array $criteria) { return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->count($criteria); } The underlying implementation, described in Doctrine\ORM\Persisters\ Entity\EntityPersister accepts a Criteria. <?php /** * Count entities (optionally filtered by a criteria) * * @param array|\Doctrine\Common\Collections\Criteria $criteria * * @return int */ public function count($criteria = []); The bug is that the array type constraint in EntityRepository.count just prevent me from doing so. However, if I manually remove this constraint in the dependency code, passing a Criteria works fine. My solution would be to just remove the type constraint, and everything would work fine. Is my explanation now clearer ? — You are receiving this because you were assigned. Reply to this email directly, view it on GitHub , or mute the thread .
@Ocramius commented on GitHub (Feb 5, 2018): Yes, that's clearer, but it won't be done. Please use the Selectable API instead. On 5 Feb 2018 20:09, "Antoine Beyet" <notifications@github.com> wrote: > Hi. > > Thank you for your time. However, I think we misunderstood. > > Let me try to reformulate. > > Currently in Doctrine\ORM\EntityRepository, we have that piece of code > (which accepts only array) > > <?php /** * Counts entities by a set of criteria. * * @todo Add this method to `ObjectRepository` interface in the next major release * * @param array $criteria * * @return int The cardinality of the objects that match the given criteria. */ public function count(array $criteria) { return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->count($criteria); } > > The underlying implementation, described in Doctrine\ORM\Persisters\ > Entity\EntityPersister accepts a Criteria. > > <?php /** * Count entities (optionally filtered by a criteria) * * @param array|\Doctrine\Common\Collections\Criteria $criteria * * @return int */ public function count($criteria = []); > > The bug is that the array type constraint in EntityRepository.count just > prevent me from doing so. However, if I manually remove this constraint in > the dependency code, passing a Criteria works fine. > > My solution would be to just remove the type constraint, and everything > would work fine. > > Is my explanation now clearer ? > > — > You are receiving this because you were assigned. > Reply to this email directly, view it on GitHub > <https://github.com/doctrine/doctrine2/issues/7037#issuecomment-363189007>, > or mute the thread > <https://github.com/notifications/unsubscribe-auth/AAJakCIpOCU8K-60oKKf2E1KCoi9X9-nks5tR1H0gaJpZM4R4nx2> > . >
Author
Owner

@dorian53 commented on GitHub (Apr 29, 2020):

Hello,

The comment Criteria is very ambigous ! I had the same problem...

@dorian53 commented on GitHub (Apr 29, 2020): Hello, The comment Criteria is very ambigous ! I had the same problem...
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5870