PHP error thrown if a one-to-one relationship cannot be retrieved #6833

Closed
opened 2026-01-22 15:39:46 +01:00 by admin · 0 comments
Owner

Originally created by @gregtyler on GitHub (Sep 21, 2021).

Bug Report

Q A
BC Break Sorry, I don't know what this means
Version 2.9.3

Summary

PHP error thrown if a one-to-one relationship cannot be retrieved.

I can't profess to understand this too much, but it has come up in live system due to a combination of Doctrine, JMSSerializer and the SoftDeleteable filter from doctrine-extensions. I've managed to narrow it down to the following:

Current behavior

When UnitOfWork->createEntity is called, it fetches related records to make them part of the object returned. For bidirectional one-to-one relationships, in certain circumstances, it uses EntityManager->find to do this, then calls spl_object_hash() and ReflectionProperty->setValue() with the result.

If find doesn't find an object then it will return null, which is an invalid argument to both of those functions. Hence one of the following errors occurs:

spl_object_hash(): Argument #1 ($object) must be of type object, null given
Exception: [ReflectionProperty::setValue(): Argument #1 ($objectOrValue) must be of type object, null given]

(The first error is what happens when I recreate locally, the second is what we saw on our live system. This has only started happening since upgrading to PHP 8.)

I believe the result of Entitymanager->find needs to be checked to ensure it is an object.

How to reproduce

See #9028 for a failing test case and suggested fix.

/** @Entity */
class Customer
{
    /**
     * One Customer has One Cart.
     * @OneToOne(targetEntity="Cart", mappedBy="customer")
     */
    private $cart;
}

/** @Entity */
class Cart
{
    /**
     * One Cart has One Customer.
     * @OneToOne(targetEntity="Customer", inversedBy="cart")
     * @JoinColumn(name="customer_id", referencedColumnName="id")
     */
    private $customer;
}

$uow = new UnitOfWork($this->_em);
$hints = ['fetchMode' => [Cart::class => ['customer' => ClassMetadata::FETCH_EAGER]]];
$cart = $uow->createEntity(Cart::class, ['id' => 1, 'customer' => 24252], $hints);

$this->assertEquals(null, $cart->customer);

This throws:

spl_object_hash(): Argument #1 ($object) must be of type object, null given

Expected behavior

The error shouldn't throw and $cart->customer should be null.

Originally created by @gregtyler on GitHub (Sep 21, 2021). ### Bug Report | Q | A |------------ | ------ | BC Break | Sorry, I don't know what this means | Version | 2.9.3 #### Summary PHP error thrown if a one-to-one relationship cannot be retrieved. I can't profess to understand this too much, but it has come up in live system due to a combination of Doctrine, JMSSerializer and the SoftDeleteable filter from doctrine-extensions. I've managed to narrow it down to the following: #### Current behavior When `UnitOfWork->createEntity` is called, it fetches related records to make them part of the object returned. For bidirectional one-to-one relationships, in certain circumstances, it uses `EntityManager->find` to do this, then calls `spl_object_hash()` and `ReflectionProperty->setValue()` with the result. If `find` doesn't find an object then it will return `null`, which is an invalid argument to both of those functions. Hence one of the following errors occurs: ``` spl_object_hash(): Argument #1 ($object) must be of type object, null given ``` ``` Exception: [ReflectionProperty::setValue(): Argument #1 ($objectOrValue) must be of type object, null given] ``` (The first error is what happens when I recreate locally, the second is what we saw on our live system. This has only started happening since upgrading to PHP 8.) I believe the result of `Entitymanager->find` needs to be checked to ensure it is an object. #### How to reproduce See #9028 for a failing test case and suggested fix. ```php /** @Entity */ class Customer { /** * One Customer has One Cart. * @OneToOne(targetEntity="Cart", mappedBy="customer") */ private $cart; } /** @Entity */ class Cart { /** * One Cart has One Customer. * @OneToOne(targetEntity="Customer", inversedBy="cart") * @JoinColumn(name="customer_id", referencedColumnName="id") */ private $customer; } $uow = new UnitOfWork($this->_em); $hints = ['fetchMode' => [Cart::class => ['customer' => ClassMetadata::FETCH_EAGER]]]; $cart = $uow->createEntity(Cart::class, ['id' => 1, 'customer' => 24252], $hints); $this->assertEquals(null, $cart->customer); ``` This throws: > spl_object_hash(): Argument #1 ($object) must be of type object, null given #### Expected behavior The error shouldn't throw and `$cart->customer` should be null.
admin closed this issue 2026-01-22 15:39:46 +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#6833