Skip to content

Loading…

DDC-202: Left Joining on an empty previous join results spl_object_hash warning #2696

Closed
doctrinebot opened this Issue · 7 comments

1 participant

@doctrinebot

Jira issue originally created by user russ:

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.

@doctrinebot

Comment created by romanb:

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

I mean sth like this:

private $foos = array();

?

@doctrinebot

Comment created by romanb:

I will try to reproduce this.

@doctrinebot

Comment created by russ:

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](http://www.doctrine-project.org/jira/browse/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?

@doctrinebot

Comment created by romanb:

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

@doctrinebot

Comment created by romanb:

This should be fixed now in trunk.

@doctrinebot

Issue was closed with resolution "Fixed"

@doctrinebot

Comment created by russ:

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

@doctrinebot doctrinebot added this to the 2.0-ALPHA4 milestone
@doctrinebot doctrinebot closed this
@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.