Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-202

Left Joining on an empty previous join results spl_object_hash warning

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-ALPHA3
    • Fix Version/s: 2.0-ALPHA4
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      I've marked this as minor because it does not seem to affect anything, other than raising a PHP warning, but that in itself suggests something is amiss somewhere.

      When joining twice (or more), all the joins must return some rows, else the warning:

       
      Warning: spl_object_hash() expects parameter 1 to be object, array given in... /etc/etc/.../ObjectHydrator.php line 269
      

      is raised.

      In my particular example, I am simulating a ManyToMany relationship via a join table, so have relations set up either side as OneToMany and ManyToOne. In order to retrieve the "many" records, I need to first join the link table, then join the records that the link table specifies.

      If the link table join returns some rows then everything passes without incident, however if the link join returns no rows, then the above warning is raised.

        Activity

        Hide
        Roman S. Borschel added a comment -

        Interesting. You're not initializing collections as arrays, are you?

        I mean sth like this:

        private $foos = array();
        

        ?

        Show
        Roman S. Borschel added a comment - Interesting. You're not initializing collections as arrays, are you? I mean sth like this: private $foos = array(); ?
        Hide
        Roman S. Borschel added a comment -

        I will try to reproduce this.

        Show
        Roman S. Borschel added a comment - I will try to reproduce this.
        Hide
        Russ Flynn (rooster) added a comment -

        No, no parameter is being initialised.

        Array hydration works fine also, so currently I have this rather interesting dql:

            $dql = "SELECT p, c, etl FROM PdfTemplate p
                    INNER JOIN p.collection c 
                    LEFT JOIN p.emailTemplateLinks etl ";
            if ($hydrationMode == \Doctrine\ORM\Query::HYDRATE_ARRAY)
            {
              // Workaround whilst waiting for #DDC-202
              // Empty joins cause spl_object_hash warning
              $dql .= " LEFT JOIN etl.emailTemplate et";
              $dql = str_replace("etl FROM", "etl, et FROM", $dql);
            }
            $dql.=  " WHERE c.id = :collection_id";
            $q = $this->_em->createQuery($dql);
            $q->setParameter("collection_id", $collectionId);
            
            return $q->execute(array(), $hydrationMode);
        

        For reference, here are the other class annotations:

        class PdfTemplate extends sfDoctrineActiveEntity
        {
        /**
           * @Id
           * @GeneratedValue(strategy="AUTO")
           * @Column(type="integer")
           *
           * @var integer
           */
          protected $id;
        
          /**
           * @ManyToOne(targetEntity="Collection")
           * @JoinColumn(name="collection_id", type="integer", referencedColumnName="id")
           *
           * @var Collection
           */
          protected $collection;
        
          /**
           * @Column(type="string")
           *
           * @var string
           */
          protected $description;
        
          /**
           * @Column(type="text")
           *
           * @var string
           */
          protected $content;
        
          /**
           * Emails linked to this pdf
           *
           * @var array
           */
          protected $linkedEmailTemplates = null;
        
          /**
           * @OneToMany(targetEntity="EmailTemplatePdfTemplate", mappedBy="emailTemplate")
           * 
           * @var array
           */
          protected $emailTemplateLinks;
        
        .......
        
        }
        
        class EmailTemplate extends sfDoctrineActiveEntity
        {
          /**
           * @Id
           * @GeneratedValue(strategy="AUTO")
           * @Column(type="integer")
           *
           * @var integer
           */
          protected $id;
        
          /**
           * @ManyToOne(targetEntity="Collection")
           * @JoinColumn(name="collection_id", referencedColumnName="id")
           *
           * @var Collection
           */
          protected $collection;
        
        
          /**
           * @Column(type="string")
           *
           * @var string
           */
          protected $description;
        
          /**
           * @Column(type="string")
           *
           * @var string
           */
          protected $subject;
        
          /**
           * @Column(type="string")
           *
           * @var string
           */
          protected $defaultFromAddress;
        
        
          /**
           * @Column(type="string", nullable="true")
           *
           * @var string
           */
          protected $defaultReplyToAddress;
        
          /**
           * @Column(type="string", nullable="true")
           *
           * @var array
           */
          protected $defaultCCAddresses; // Fixme - the Doctrine array type is broken!
        
          /**
           * @Column(type="text")
           *
           * @var string
           */
          protected $messageBody;
        
          /**
           * Pdf templates linked to/attached to this email
           *
           * @var array
           */
          protected $linkedPdfTemplates = null;
        
          /**
           * @OneToMany(targetEntity="EmailTemplatePdfTemplate", mappedBy="emailTemplate")
           * 
           * @var array
           */
          protected $pdfTemplateLinks;
        
        .....
        }
        
        class EmailTemplatePdfTemplate
        {
          /**
            * @Id @Column(type="integer")
            * @GeneratedValue(strategy="AUTO")
            */
          protected $id;
        
          /**
           * @ManyToOne(targetEntity="EmailTemplate")
           * @JoinColumn(name="email_template_id", referencedColumnName="id")
           */
          protected $emailTemplate;
        
          /**
           * @ManyToOne(targetEntity="PdfTemplate")
           * @JoinColumn(name="pdf_template_id", referencedColumnName="id")
           */
          protected $pdfTemplate;
        
        ....
        
        }
        

        As you can see the only properties that are initialised (as null) are not annotated and are dealt with by the class internally. Could they have something to do with it?

        Show
        Russ Flynn (rooster) added a comment - No, no parameter is being initialised. Array hydration works fine also, so currently I have this rather interesting dql: $dql = "SELECT p, c, etl FROM PdfTemplate p INNER JOIN p.collection c LEFT JOIN p.emailTemplateLinks etl "; if ($hydrationMode == \Doctrine\ORM\Query::HYDRATE_ARRAY) { // Workaround whilst waiting for #DDC-202 // Empty joins cause spl_object_hash warning $dql .= " LEFT JOIN etl.emailTemplate et" ; $dql = str_replace( "etl FROM" , "etl, et FROM" , $dql); } $dql.= " WHERE c.id = :collection_id" ; $q = $ this ->_em->createQuery($dql); $q->setParameter( "collection_id" , $collectionId); return $q->execute(array(), $hydrationMode); For reference, here are the other class annotations: class PdfTemplate extends sfDoctrineActiveEntity { /** * @Id * @GeneratedValue(strategy= "AUTO" ) * @Column(type= "integer" ) * * @ var integer */ protected $id; /** * @ManyToOne(targetEntity= "Collection" ) * @JoinColumn(name= "collection_id" , type= "integer" , referencedColumnName= "id" ) * * @ var Collection */ protected $collection; /** * @Column(type= "string" ) * * @ var string */ protected $description; /** * @Column(type= "text" ) * * @ var string */ protected $content; /** * Emails linked to this pdf * * @ var array */ protected $linkedEmailTemplates = null ; /** * @OneToMany(targetEntity= "EmailTemplatePdfTemplate" , mappedBy= "emailTemplate" ) * * @ var array */ protected $emailTemplateLinks; ....... } class EmailTemplate extends sfDoctrineActiveEntity { /** * @Id * @GeneratedValue(strategy= "AUTO" ) * @Column(type= "integer" ) * * @ var integer */ protected $id; /** * @ManyToOne(targetEntity= "Collection" ) * @JoinColumn(name= "collection_id" , referencedColumnName= "id" ) * * @ var Collection */ protected $collection; /** * @Column(type= "string" ) * * @ var string */ protected $description; /** * @Column(type= "string" ) * * @ var string */ protected $subject; /** * @Column(type= "string" ) * * @ var string */ protected $defaultFromAddress; /** * @Column(type= "string" , nullable= " true " ) * * @ var string */ protected $defaultReplyToAddress; /** * @Column(type= "string" , nullable= " true " ) * * @ var array */ protected $defaultCCAddresses; // Fixme - the Doctrine array type is broken! /** * @Column(type= "text" ) * * @ var string */ protected $messageBody; /** * Pdf templates linked to/attached to this email * * @ var array */ protected $linkedPdfTemplates = null ; /** * @OneToMany(targetEntity= "EmailTemplatePdfTemplate" , mappedBy= "emailTemplate" ) * * @ var array */ protected $pdfTemplateLinks; ..... } class EmailTemplatePdfTemplate { /** * @Id @Column(type= "integer" ) * @GeneratedValue(strategy= "AUTO" ) */ protected $id; /** * @ManyToOne(targetEntity= "EmailTemplate" ) * @JoinColumn(name= "email_template_id" , referencedColumnName= "id" ) */ protected $emailTemplate; /** * @ManyToOne(targetEntity= "PdfTemplate" ) * @JoinColumn(name= "pdf_template_id" , referencedColumnName= "id" ) */ protected $pdfTemplate; .... } As you can see the only properties that are initialised (as null) are not annotated and are dealt with by the class internally. Could they have something to do with it?
        Hide
        Roman S. Borschel added a comment -

        I dont think so. Your code looks absolutely correct. I am working on this. I already got it reproduced in the test suite.

        Show
        Roman S. Borschel added a comment - I dont think so. Your code looks absolutely correct. I am working on this. I already got it reproduced in the test suite.
        Hide
        Roman S. Borschel added a comment -

        This should be fixed now in trunk.

        Show
        Roman S. Borschel added a comment - This should be fixed now in trunk.
        Hide
        Russ Flynn (rooster) added a comment -

        Works for me when I remove my workaround (above). Good stuff.

        Show
        Russ Flynn (rooster) added a comment - Works for me when I remove my workaround (above). Good stuff.

          People

          • Assignee:
            Roman S. Borschel
            Reporter:
            Russ Flynn (rooster)
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: