Uploaded image for project: 'Doctrine 2 - ORM'
  1. Doctrine 2 - ORM
  2. DDC-3104

Invalid count on EXTRA LAZY collection of SINGLE TABLE entities

    Details

    • Type: Bug
    • Status: Open
    • Priority: 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
          ocramius 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
          ocramius 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
          deatheriam 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
          deatheriam 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
          ocramius Marco Pivetta added a comment -

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

          Show
          ocramius Marco Pivetta added a comment - Ah, I see what you mean now. Sorry, I was confusing this with a joined table inheritance.
          Hide
          vigintas 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 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:
              beberlei Benjamin Eberlei
              Reporter:
              deatheriam Oleg Namaka
            • Votes:
              1 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated: