diff --git a/UPGRADE.md b/UPGRADE.md
index 9ee676758d4..c93dd986960 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -1,5 +1,10 @@
# Upgrade to 3.0
+## BC BREAK: Changed `EntityManagerInterface#refresh($entity)`, `EntityManagerDecorator#refresh($entity)` and `UnitOfWork#refresh($entity)` signatures
+
+The new signatures of these methods add an optional `LockMode|int|null $lockMode`
+param with default `null` value (no lock).
+
## BC Break: Removed AnnotationDriver
The annotation driver and anything related to annotation has been removed.
diff --git a/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php b/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php
index 72818cad2a7..c546efd8a4a 100644
--- a/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php
+++ b/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php
@@ -24,9 +24,6 @@
use Doctrine\ORM\UnitOfWork;
use Doctrine\Persistence\ObjectManagerDecorator;
-use function func_get_arg;
-use function func_num_args;
-
/**
* Base class for EntityManager decorators
*
@@ -133,14 +130,8 @@ public function find(string $className, mixed $id, LockMode|int|null $lockMode =
return $this->wrapped->find($className, $id, $lockMode, $lockVersion);
}
- public function refresh(object $object): void
+ public function refresh(object $object, LockMode|int|null $lockMode = null): void
{
- $lockMode = null;
-
- if (func_num_args() > 1) {
- $lockMode = func_get_arg(1);
- }
-
$this->wrapped->refresh($object, $lockMode);
}
diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php
index dc4d3cdedb8..ef80a6b4811 100644
--- a/lib/Doctrine/ORM/EntityManager.php
+++ b/lib/Doctrine/ORM/EntityManager.php
@@ -496,16 +496,6 @@ public function remove(object $object): void
$this->unitOfWork->remove($object);
}
- /**
- * Refreshes the persistent state of an entity from the database,
- * overriding any local changes that have not yet been persisted.
- *
- * @psalm-param LockMode::*|null $lockMode
- *
- * @throws ORMInvalidArgumentException
- * @throws ORMException
- * @throws TransactionRequiredException
- */
public function refresh(object $object, LockMode|int|null $lockMode = null): void
{
$this->errorIfClosed();
diff --git a/lib/Doctrine/ORM/EntityManagerInterface.php b/lib/Doctrine/ORM/EntityManagerInterface.php
index 379b19c88ce..db8e1f803e8 100644
--- a/lib/Doctrine/ORM/EntityManagerInterface.php
+++ b/lib/Doctrine/ORM/EntityManagerInterface.php
@@ -17,7 +17,6 @@
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Persistence\ObjectManager;
-/** @method void refresh(object $object, LockMode|int|null $lockMode = null) */
interface EntityManagerInterface extends ObjectManager
{
/**
@@ -133,6 +132,21 @@ public function createQueryBuilder(): QueryBuilder;
*/
public function find(string $className, mixed $id, LockMode|int|null $lockMode = null, int|null $lockVersion = null): object|null;
+ /**
+ * Refreshes the persistent state of an object from the database,
+ * overriding any local changes that have not yet been persisted.
+ *
+ * @param LockMode|int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants
+ * or NULL if no specific lock mode should be used
+ * during the search.
+ * @psalm-param LockMode::*|null $lockMode
+ *
+ * @throws ORMInvalidArgumentException
+ * @throws ORMException
+ * @throws TransactionRequiredException
+ */
+ public function refresh(object $object, LockMode|int|null $lockMode = null): void;
+
/**
* Gets a reference to the entity identified by the given type and identifier
* without actually loading it, if the entity is not yet loaded.
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 1c114f5fd1f..a07797348df 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -64,8 +64,6 @@
use function assert;
use function count;
use function current;
-use function func_get_arg;
-use function func_num_args;
use function get_debug_type;
use function implode;
use function in_array;
@@ -1790,19 +1788,15 @@ private function doDetach(
* Refreshes the state of the given entity from the database, overwriting
* any local, unpersisted changes.
*
+ * @psalm-param LockMode::*|null $lockMode
+ *
* @throws InvalidArgumentException If the entity is not MANAGED.
* @throws TransactionRequiredException
*/
- public function refresh(object $entity): void
+ public function refresh(object $entity, LockMode|int|null $lockMode = null): void
{
$visited = [];
- $lockMode = null;
-
- if (func_num_args() > 1) {
- $lockMode = func_get_arg(1);
- }
-
$this->doRefresh($entity, $visited, $lockMode);
}
diff --git a/psalm.xml b/psalm.xml
index 968f208c50c..6f11cbb315d 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -88,9 +88,6 @@
-
-
-
diff --git a/tests/Doctrine/Performance/Mock/NonProxyLoadingEntityManager.php b/tests/Doctrine/Performance/Mock/NonProxyLoadingEntityManager.php
index e98030e7782..39db18da09f 100644
--- a/tests/Doctrine/Performance/Mock/NonProxyLoadingEntityManager.php
+++ b/tests/Doctrine/Performance/Mock/NonProxyLoadingEntityManager.php
@@ -201,9 +201,9 @@ public function detach(object $object): void
$this->realEntityManager->detach($object);
}
- public function refresh(object $object): void
+ public function refresh(object $object, LockMode|int|null $lockMode = null): void
{
- $this->realEntityManager->refresh($object);
+ $this->realEntityManager->refresh($object, $lockMode);
}
public function flush(): void