Undefined array key when calling refresh() after updating to 2.20.1 #7459

Open
opened 2026-01-22 15:51:56 +01:00 by admin · 6 comments
Owner

Originally created by @mcapinha-mxp on GitHub (Jan 8, 2025).

Bug Report

Q A
Version 2.20.1
Previous Version if the bug is a regression 2.20.0

Summary

After updating to 2.20.1, in some circumstances, calling refresh() on an Entity returns an Undefined array key error

Current behavior

When calling refresh() on an entity, an Undefined array key exception is thrown.

Expected behavior

The entity should be refreshed from the db and no error shown.

How to reproduce

I haven't been able to produce a minimal reproducible example, probably because our Entity setup is very complex.
However, reverting the changes in blem solves the issue for us.

Originally created by @mcapinha-mxp on GitHub (Jan 8, 2025). ### Bug Report <!-- Fill in the relevant information below to help triage your issue. --> | Q | A |-------------------------------------------- | ------ | Version | 2.20.1 | Previous Version if the bug is a regression | 2.20.0 #### Summary After updating to 2.20.1, in some circumstances, calling `refresh()` on an Entity returns an `Undefined array key` error #### Current behavior When calling `refresh()` on an entity, an `Undefined array key` exception is thrown. #### Expected behavior The entity should be refreshed from the db and no error shown. #### How to reproduce I haven't been able to produce a minimal reproducible example, probably because our Entity setup is very complex. However, reverting the changes in [blem](https://github.com/doctrine/orm/commit/7d1b24f3b1fde6e12385c299ba6ea4b0da385031#diff-2cbf87f941a104db9881228f86e16e3c9f894a88c7ac9245b0632de36b8b887cR2476) solves the issue for us.
Author
Owner

@mcapinha-mxp commented on GitHub (Jan 8, 2025):

Here's a stack trace from our Symfony application:

ErrorException:
Warning: Undefined array key 6873

  at vendor/doctrine/orm/src/UnitOfWork.php:2479
  at Doctrine\ORM\UnitOfWork->doRefresh(object(HistoryItem), array(object(Report), object(HistoryItem), object(HistoryItem)), null)
     (vendor/doctrine/orm/src/UnitOfWork.php:2515)
  at Doctrine\ORM\UnitOfWork->cascadeRefresh(object(Report), array(object(Report), object(HistoryItem), object(HistoryItem)), null)
     (vendor/doctrine/orm/src/UnitOfWork.php:2476)
  at Doctrine\ORM\UnitOfWork->doRefresh(object(Report), array(object(Report), object(HistoryItem), object(HistoryItem)), null)
     (vendor/doctrine/orm/src/UnitOfWork.php:2439)
  at Doctrine\ORM\UnitOfWork->refresh(object(Report), null)
     (vendor/doctrine/orm/src/EntityManager.php:729)
  at Doctrine\ORM\EntityManager->refresh(object(Report))
     (src/AppBundle/Service/ExpenseManager.php:388)
  at AppBundle\Service\ExpenseManager->save(object(Bill), object(Bill))
     (src/AppBundle/Controller/PROJECT/ExpenseController.php:417)
  at AppBundle\Controller\PROJECT\ExpenseController->editAction(object(Request), object(CacheService), null, 0, object(Report), object(ExpenseManagerGhostFfb6450), object(AllowanceManager), null)
     (vendor/symfony/http-kernel/HttpKernel.php:181)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:76)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:197)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (public/index.php:28)              
@mcapinha-mxp commented on GitHub (Jan 8, 2025): Here's a stack trace from our Symfony application: ``` ErrorException: Warning: Undefined array key 6873 at vendor/doctrine/orm/src/UnitOfWork.php:2479 at Doctrine\ORM\UnitOfWork->doRefresh(object(HistoryItem), array(object(Report), object(HistoryItem), object(HistoryItem)), null) (vendor/doctrine/orm/src/UnitOfWork.php:2515) at Doctrine\ORM\UnitOfWork->cascadeRefresh(object(Report), array(object(Report), object(HistoryItem), object(HistoryItem)), null) (vendor/doctrine/orm/src/UnitOfWork.php:2476) at Doctrine\ORM\UnitOfWork->doRefresh(object(Report), array(object(Report), object(HistoryItem), object(HistoryItem)), null) (vendor/doctrine/orm/src/UnitOfWork.php:2439) at Doctrine\ORM\UnitOfWork->refresh(object(Report), null) (vendor/doctrine/orm/src/EntityManager.php:729) at Doctrine\ORM\EntityManager->refresh(object(Report)) (src/AppBundle/Service/ExpenseManager.php:388) at AppBundle\Service\ExpenseManager->save(object(Bill), object(Bill)) (src/AppBundle/Controller/PROJECT/ExpenseController.php:417) at AppBundle\Controller\PROJECT\ExpenseController->editAction(object(Request), object(CacheService), null, 0, object(Report), object(ExpenseManagerGhostFfb6450), object(AllowanceManager), null) (vendor/symfony/http-kernel/HttpKernel.php:181) at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1) (vendor/symfony/http-kernel/HttpKernel.php:76) at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true) (vendor/symfony/http-kernel/Kernel.php:197) at Symfony\Component\HttpKernel\Kernel->handle(object(Request)) (public/index.php:28) ```
Author
Owner

@mcapinha commented on GitHub (Jan 11, 2025):

Hello.

I add a test that reproduces this issue in 2.20.1 and passes in 2.20.0.
AFAICT, this reproduces what our application is doing at the point the error is triggered.

The commit is in this branch in my forked repo:
https://github.com/mcapinha/orm/tree/2.20.1_refresh_issue

Can you please have a look?

@mcapinha commented on GitHub (Jan 11, 2025): Hello. I add a test that reproduces this issue in 2.20.1 and passes in 2.20.0. AFAICT, this reproduces what our application is doing at the point the error is triggered. The commit is in this branch in my forked repo: https://github.com/mcapinha/orm/tree/2.20.1_refresh_issue Can you please have a look?
Author
Owner

@greg0ire commented on GitHub (Jan 11, 2025):

cc @goetas

@greg0ire commented on GitHub (Jan 11, 2025): cc @goetas
Author
Owner

@goetas commented on GitHub (Jan 11, 2025):

Thanks for the super well prepared reproducer.

This is an interesting edgecase present in past versions of doctrine.
It happens because an there is an attempt to refresh an entity that has not yet been flushed (thus not in the database).

What is the expected behavior of this code?

**
 * @ORM\Entity
 */
class Report {
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;
    /**
     * @ORM\Column
     */
    public $name;

    public function __construct($name) {
        $this->name = $name;
    }
}
$user = new Report('foo');

$em->persist($foo);
$em->refresh($foo);

Currently most doctrine versions will trigger the error Undefined array key.... If you use a database that supports sequences you might get e different error (did not spend time verifying it).

I see at least two options.

  1. trigger and exception telling that the object can not be refreshed since it has not been flushed yet
  2. silently ignore the not flushed entities
  3. silently ignore not flushed entities if part of a cascade refresh but trigger an exception if the refresh has been asked explicitly on an entity that has not been saved.

option 2 seems the most backward compatible approach, 3 seems the best (a little more complex but not that much)

@goetas commented on GitHub (Jan 11, 2025): Thanks for the super well prepared reproducer. This is an interesting edgecase present in past versions of doctrine. It happens because an there is an attempt to refresh an entity that has not yet been flushed (thus not in the database). What is the expected behavior of this code? ```php ** * @ORM\Entity */ class Report { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ public $id; /** * @ORM\Column */ public $name; public function __construct($name) { $this->name = $name; } } $user = new Report('foo'); $em->persist($foo); $em->refresh($foo); ``` Currently most doctrine versions will trigger the error `Undefined array key...`. If you use a database that supports sequences you might get e different error (did not spend time verifying it). I see at least two options. 1) trigger and exception telling that the object can not be refreshed since it has not been flushed yet 2) silently ignore the not flushed entities 3) silently ignore not flushed entities if part of a cascade refresh but trigger an exception if the refresh has been asked explicitly on an entity that has not been saved. option 2 seems the most backward compatible approach, 3 seems the best (a little more complex but not that much)
Author
Owner

@greg0ire commented on GitHub (Jan 11, 2025):

Maybe 2 + a deprecation, and then 1 in doctrine 4?

@greg0ire commented on GitHub (Jan 11, 2025): Maybe 2 + a deprecation, and then 1 in doctrine 4?
Author
Owner

@joey-bolts commented on GitHub (Mar 25, 2025):

This might be related to https://github.com/doctrine/orm/pull/10065

@joey-bolts commented on GitHub (Mar 25, 2025): This might be related to https://github.com/doctrine/orm/pull/10065
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7459