Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mcapinha-mxp opened this issue Jan 8, 2025 · 5 comments
Open

Comments

@mcapinha-mxp
Copy link

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.

@mcapinha-mxp
Copy link
Author

mcapinha-mxp commented 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
Copy link

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?

@greg0ire
Copy link
Member

cc @goetas

@goetas
Copy link
Member

goetas commented 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)

@greg0ire
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants