DDC-669: order of fields in sql query and parameters to be bound to the dbal's statement is different #5179

doctrinebot opened this Issue Jul 5, 2010 · 3 comments

2 participants


Jira issue originally created by user sergei.lissovski:

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:

 * @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:

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:

    [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


Comment created by @beberlei:

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


Issue was closed with resolution "Duplicate"


Comment created by sergei.lissovski:

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

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot added this to the 2.0-BETA3 milestone Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment