Skip to content

Loading…

DDC-3104: Invalid count on EXTRA LAZY collection of SINGLE TABLE entities #3880

Open
doctrinebot opened this Issue · 5 comments

2 participants

@doctrinebot

Jira issue originally created by user deatheriam:

* @ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\Table(name="entity_promotion")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({
 *     "brand"           = "BrandPromotion",
 *     "category"        = "CategoryPromotion",
 * })
 */
abstract class EntityPromotionAbstract

**** CategoryPromotion entity:

 * @ORM\Entity
 */
class CategoryPromotion extends EntityPromotionAbstract
{
    /****
     * Category
     *
     * @var Category
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="CategoryPromotions")
     * @ORM\JoinColumn(name="instance*id", referencedColumnName="category*id")
     */
    protected $Category;
...
}

**** BrandPromotion entity:

 * @ORM\Entity
 */
class BrandPromotion extends EntityPromotionAbstract
{
    /****
     * Brand
     *
     * @var Brand
     * @ORM\ManyToOne(targetEntity="Brand", inversedBy="BrandPromotions")
     * @ORM\JoinColumn(name="instance*id", referencedColumnName="brand*id")
     */
    protected $Brand;
}

**** Brand entity:

    /****
     * Associated BrandPromotions
     *
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\OneToMany(targetEntity="BrandPromotion", mappedBy="Brand", fetch="EXTRA_LAZY")
     */
    protected $BrandPromotions;

**** Category entity:

    /****
     * Associated CategoryPromotions
     *
     * @var \Doctrine\Common\Collections\ArrayCollection|\Doctrine\ORM\PersistentCollection
     *
     * @ORM\OneToMany(targetEntity="CategoryPromotion", mappedBy="Category", fetch="EXTRA_LAZY")
     */
    protected $CategoryPromotions;
  • When Brand::BrandPromotions collection is not initialized, calling count on it will return a count of BrandPromotion and CategoryPromotion elements, but calling isEmpty will return a count of BrandPromotion entities only.
  • \Doctrine\ORM\Persisters\OneToManyPersister::count does not take into account a discriminator value of 'brand':
        foreach ($targetClass->associationMappings[$mapping['mappedBy']]['joinColumns'] as $joinColumn) {
            $whereClauses[] = $joinColumn['name'] . ' = ?';

            $params[] = ($targetClass->containsForeignIdentifier)
                ? $id[$sourceClass->getFieldForColumn($joinColumn['referencedColumnName'])]
                : $id[$sourceClass->fieldNames[$joinColumn['referencedColumnName']]];
        }

  • This results in a query:
SELECT count(*) FROM entity*promotion t WHERE instance*id = ?
  • The query should include a type condition:
SELECT count(*) FROM entity*promotion t WHERE instance*id = ? AND (t.type in 'brand')
@doctrinebot

Comment created by @ocramius:

Why would the query include a type conditional? To me, it seems like the association was built between invalid data types instead.

@doctrinebot

Comment created by deatheriam:

  • Could you elaborate on what exactly you mean when you are saying, that the association was built between invalid data types?
  • Even if your statement is valid, then why calling on a initialized collection $collection->isEmpty() produces a correct result? Calling $collection->count() produces also a correct result on an initialized collection, wheres calling $collection->count() on an unitialized collection results in an invalid element count.
@doctrinebot

Comment created by @ocramius:

Ah, I see what you mean now. Sorry, I was confusing this with a joined table inheritance.

@doctrinebot

Comment created by vigintas:

Exactly same behaviour just wasted me a few hours. Shame I'll have to switch fetch mode back to LAZY until this gets fixed.

@beberlei beberlei was assigned by doctrinebot
@doctrinebot doctrinebot added the Bug label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.