DDC-1975: Binding entities to query parameters throws exception on new entity #2491

Open
opened 2026-01-22 13:55:07 +01:00 by admin · 0 comments
Owner

Originally created by @doctrinebot on GitHub (Aug 10, 2012).

Originally assigned to: @beberlei on GitHub.

Jira issue originally created by user goetas:

I have this entities:

class User{
    /****
    * ...
    */
    protected $id;
    /****
     * @ManyToOne(targetEntity="Phone")
     * @JoinColumn(name="address_id", referencedColumnName="id")
     */
    protected $phone;
}

class Phone{
    /****
    * ...
    */
    protected $id;
}

when run this query:

$phone = new Phone();

$dql = $em->createQueryBuilder();
$dql->from("User", "u");
$dql->andWhere("u.phone = :phone");     
$dql->setParameter("phone", $phone);    

dql->getQuery()->getResult();   

i get the exception: Binding entities to query parameters only allowed for entities that have an identifier.

the expected query is:
SELECT * FROM user WHERE phone_id = NULL;

the involved ORM component is AbstractQuery::convertObjectParameterToScalarValue

changing this method, form


protected function convertObjectParameterToScalarValue($value)
{
    $class = $this->*em->getClassMetadata(get*class($value));

    if ($class->isIdentifierComposite) {
        throw new \InvalidArgumentException(
            "Binding an entity with a composite primary key to a query is not supported. " .
            "You should split the parameter into the explicit fields and bind them seperately."
        );
    }

    $values = ($this->*em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE*MANAGED)
        ? $this->_em->getUnitOfWork()->getEntityIdentifier($value)
        : $class->getIdentifierValues($value);

    $value = $values[$class->getSingleIdentifierFieldName()];

    if ( ! $value) {
        throw new \InvalidArgumentException(
            "Binding entities to query parameters only allowed for entities that have an identifier."
        );
    }

    return $value;
}

to

protected function convertObjectParameterToScalarValue($value)
{
    $class = $this->*em->getClassMetadata(get*class($value));

    if ($class->isIdentifierComposite) {
        throw new \InvalidArgumentException(
            "Binding an entity with a composite primary key to a query is not supported. " .
            "You should split the parameter into the explicit fields and bind them seperately."
        );
    }
    $state = $this->_em->getUnitOfWork()->getEntityState($value);

    $values = ($state === UnitOfWork::STATE_MANAGED)
        ? $this->_em->getUnitOfWork()->getEntityIdentifier($value)
        : $class->getIdentifierValues($value);

    $value = $values[$class->getSingleIdentifierFieldName()];

    if ( ! $value && $state !== UnitOfWork::STATE_NEW) {
        throw new \InvalidArgumentException(
            "Binding entities to query parameters only allowed for entities that have an identifier."
        );
    }

    return $value;
}

.

the modified method check if the 'phone' entity state is new, and if it is true return null.

Originally created by @doctrinebot on GitHub (Aug 10, 2012). Originally assigned to: @beberlei on GitHub. Jira issue originally created by user goetas: I have this entities: ``` java class User{ /**** * ... */ protected $id; /**** * @ManyToOne(targetEntity="Phone") * @JoinColumn(name="address_id", referencedColumnName="id") */ protected $phone; } class Phone{ /**** * ... */ protected $id; } ``` when run this query: ``` java $phone = new Phone(); $dql = $em->createQueryBuilder(); $dql->from("User", "u"); $dql->andWhere("u.phone = :phone"); $dql->setParameter("phone", $phone); dql->getQuery()->getResult(); ``` i get the exception: **Binding entities to query parameters only allowed for entities that have an identifier.** the expected query is: SELECT \* FROM user WHERE phone_id = NULL; the involved ORM component is **AbstractQuery::convertObjectParameterToScalarValue** changing this method, form ``` java protected function convertObjectParameterToScalarValue($value) { $class = $this->*em->getClassMetadata(get*class($value)); if ($class->isIdentifierComposite) { throw new \InvalidArgumentException( "Binding an entity with a composite primary key to a query is not supported. " . "You should split the parameter into the explicit fields and bind them seperately." ); } $values = ($this->*em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE*MANAGED) ? $this->_em->getUnitOfWork()->getEntityIdentifier($value) : $class->getIdentifierValues($value); $value = $values[$class->getSingleIdentifierFieldName()]; if ( ! $value) { throw new \InvalidArgumentException( "Binding entities to query parameters only allowed for entities that have an identifier." ); } return $value; } ``` to ``` java protected function convertObjectParameterToScalarValue($value) { $class = $this->*em->getClassMetadata(get*class($value)); if ($class->isIdentifierComposite) { throw new \InvalidArgumentException( "Binding an entity with a composite primary key to a query is not supported. " . "You should split the parameter into the explicit fields and bind them seperately." ); } $state = $this->_em->getUnitOfWork()->getEntityState($value); $values = ($state === UnitOfWork::STATE_MANAGED) ? $this->_em->getUnitOfWork()->getEntityIdentifier($value) : $class->getIdentifierValues($value); $value = $values[$class->getSingleIdentifierFieldName()]; if ( ! $value && $state !== UnitOfWork::STATE_NEW) { throw new \InvalidArgumentException( "Binding entities to query parameters only allowed for entities that have an identifier." ); } return $value; } ``` . the modified method check if the 'phone' entity state is new, and if it is true return null.
admin added the Bug label 2026-01-22 13:55:07 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#2491