Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-3104

Invalid count on EXTRA LAZY collection of SINGLE TABLE entities

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.3.2
    • Fix Version/s: None
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      • This issue relates to http://www.doctrine-project.org/jira/browse/DDC-1595
      • With the following entities
        • EntityPromotionAbstract entity:
          * @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')
        

        Issue Links

          Activity

          Hide
          Marco Pivetta added a comment -

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

          Show
          Marco Pivetta added a comment - Why would the query include a type conditional? To me, it seems like the association was built between invalid data types instead.
          Hide
          Oleg Namaka added a comment -
          • 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.
          Show
          Oleg Namaka added a comment - 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.
          Hide
          Marco Pivetta added a comment -

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

          Show
          Marco Pivetta added a comment - Ah, I see what you mean now. Sorry, I was confusing this with a joined table inheritance.
          Hide
          Vigintas Labakojis added a comment -

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

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

            People

            • Assignee:
              Benjamin Eberlei
              Reporter:
              Oleg Namaka
            • Votes:
              1 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated: