Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-669

order of fields in sql query and parameters to be bound to the dbal's statement is different

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Duplicate
    • Affects Version/s: 2.0-BETA2
    • Fix Version/s: 2.0-BETA3
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None
    • Environment:
      win7, apache2, php 5.3.2

      Description

      Hi guys,

      It seems that I found a bug in the Doctrine\ORM\Persisters\BasicEntityPersister. Let me explain.

      Put it simply, I have the following entity:

      Foo.php
      /**
       * @Entity
       */
      class Foo
      {
          /**
           * @Id
           * @Column(type="integer")
           * @GeneratedValue(strategy="AUTO")
           */
          private $id;
          /**
           * @ManyToOne(targetEntity="Foo", inversedBy="children")
           * @JoinColumn(name="parent_id", referencedColumnName="id")
           */
          private $parent;
          /**
           * @OneToMany(targetEntity="Foo", mappedBy="parent")
           */
          private $children;
          /**
           * @Column(type="integer", nullable=false)
           */
          private $verticalOrder;
      
          // a bunch of getters/setters
      

      As you can see, there's a mandatory field called "verticalOrder", it is not intended to be managed manually but rather with a listener attached to onFlush event. ( In that listener, after a value for the verticalOrder is set, the uow::recomputeSingleEntityChangeSet() method is invoked, as it was suggested in documentation ).

      The thing is that when I persist an instance of this class and then invoke flush ( without providing a value for it, the verticalOrder ), Doctrine dies silently, with no exception being thrown. The easy fix can be done with adding this piece of source code to the BasicEntityPersister on line 218:

      Dumb fix
      if (!$stmt->execute()) {
          throw new \Exception('Unable to execute query: '.var_export($stmt->errorInfo(), true));
      }
      

      That was the first problem I have faced with while trying to find out why my entity is not persisted. After I have delved a bit deeper, I found out
      that the problem lies in BasicEntityPersister ::_getInsertColumnList() or in BasicEntityPersister ::_prepareUpdateData(). The thing is that order of columns in the SQL query generated by the BasicEntityPersister::_getInsertColumnList() and values to be bound to the statement and after executed is different. Line 214 in BasicEntityPersister is meant here.

      In my case it was reversed, instead of parent_id, a value for verticalOrder was inserted and vice versa.

      Array of parameters to be bound to the Doctrine\DBAL\Statement:

      Array
      (
          [verticalOrder] => 1278334736 // at the moment timestamp is used rather than MAX from the table
          [parent_id] => 
      )
      
      

      And the query that will be executed:

      INSERT INTO Foo(parent_id, verticalOrder) VALUES (?, ?)
      

      These snippets clearly illustrate the point.

      I hope I was clear in my explanations.

      I will try to devote some spare time and write tests to lock this issue, but i'm not able to say at the moment when it happens.

      All the best,
      Sergei Lissovski

        Activity

        Hide
        Benjamin Eberlei added a comment -

        This issue is a duplicate of DDC-656. which was fixed this weekend. The current master has a fix for it.

        Show
        Benjamin Eberlei added a comment - This issue is a duplicate of DDC-656 . which was fixed this weekend. The current master has a fix for it.
        Hide
        Sergei Lissovski added a comment -

        Okay, thank you for a quick response. Will take it into account.

        Show
        Sergei Lissovski added a comment - Okay, thank you for a quick response. Will take it into account.

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Sergei Lissovski
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: