#symfony #doctrine
Вопрос:
У меня есть 2 сущности, User
и Organization
/**
* @ORMEntity
*/
class User
{
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private ?int $id;
/**
* @ORMColumn(type="string", length=180, unique=true)
*/
private ?string $email;
// ...
}
/**
* @ORMEntity
*/
class Organization
{
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private ?int $id;
/**
* @ORMColumn(type="integer")
*/
private float $cron_payout_max_days_between;
// ...
}
Случайным образом, когда я обновлял или создавал новую User
строку БД, такую как эта:
$user->setEmail('some@email.com');
$this->entityManager->persist($user);
$this->entityManager->flush();
Я заметил в профилировщике Symfony, что по какой-то причине между START TRANSACTION
сущностью и COMMIT
не связанными с User
ней существами были запросы. В частности, такие запросы, как:
UPDATE organization SET cron_payout_max_days_between = ? WHERE id = ?
Это сводило меня с ума, потому что казалось случайным. На некоторых страницах это происходило. На других-нет. Иногда для нескольких строк организации, иногда для всех, иногда для одной, а иногда ни для одной.
Я понял это после того, как провел 3 часа внутри отладчика, тысячу раз заходя в UnitOfWork. Я пишу этот пост, чтобы избавить от этого разочарования кого-то другого, кто может столкнуться с такой проблемой, потому что я ничего не нашел во время поиска ответа.
Ответ №1:
Эту проблему было легко не заметить.
/**
* @ORMColumn(type="integer")
*/
private float $cron_payout_max_days_between;
тип столбца был определен как целое число, но переменная PHP была с плавающей точкой. Это означало, что доктрина ВСЕГДА будет рассматривать ценность сущности как измененную, даже если я к ней не прикасался.
Почему это происходило случайным образом с одной, многими, всеми строками? Это зависит от того, какие строки загружаются в кэш другими частями кода. В любом случае, как только EntityManager::persist()
функция была вызвана, каждый Organization
объект, который был загружен в какой-то момент, уже был отмечен для обновления, потому что float 1.0 != int 1
Я надеюсь, что это сэкономит вам несколько часов вашего времени!
Просто для ясности, исправление было изменено на:
/**
* @ORMColumn(type="integer")
*/
private int $cron_payout_max_days_between;