У меня есть следующая проблема:
Предполагается, что доктрина обновляет сущности, которые были изменены. Проблема в том, что по какой-то причине (может быть, унаследованные 32-битные системы?) Тип данных bigint обрабатывается как строка (как вы можете видеть ниже - это класс типа bigint в доктрине, есть также несколько других преобразований строки в код доктрины). ).
<?php
namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* Type that maps a database BIGINT to a PHP string.
*/
class BigIntType extends Type implements PhpIntegerMappingType
{
/**
* {@inheritdoc}
*/
public function getName()
{
return Type::BIGINT;
}
/**
* {@inheritdoc}
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getBigIntTypeDeclarationSQL($fieldDeclaration);
}
/**
* {@inheritdoc}
*/
public function getBindingType()
{
return ParameterType::STRING;
}
/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return $value === null ? null : (string) $value;
}
}
Это приводит к обновлению данных, которые не должны обновляться, поскольку средство проверки единицы работы сравнивает данные как строгие (как и должно быть), что приводит к различиям (код ниже).
// skip if value haven't changed
if ($orgValue === $actualValue) { // $orgValue = "3829784117300", $actualValue = 3829784117300
continue;
}
Конечным результатом для этого является следующий код:
$product = $productRepo->find($id);
$product->setOwnerId($ownerId); // $ownerId = 3829784117300
$this->em->flush();
Генерирует запрос, который ничего не делает ... ничего, кроме подчеркивания дб (в моем случае у меня есть несколько десятков миллионов из них). в день). Решение для частного случая выше ...
$product = $productRepo->find($id);
if ((int)$product->getOwnerId() !== $ownerId) {
$product->setOwnerId($ownerId); // $ownerId = 3829784117300
}
$this->em->flush();
Просто верно? Но ... что ты делаешь, когда у тебя 2 больших пальца? Хорошо ... 2 условия ... не имеет большого значения. Но что, если они ... 90? Хорошо ... мы можем использовать отражение, пройти через свойства объекта и проверить все.
Но ... что если где-то в цепочке отношений есть другая сущность, которую нужно проверить? И полное решение состоит в том, что мы должны рекурсивно проверять каждый атрибут сущности и его дочерних элементов и проверять наличие bigints.
Но ... разве не для этого предназначена единица работы доктрины? Зачем мне нужно повторно анализировать всю сущность и проверять что-то, что уже проверено только потому, что bigint обрабатывается как строка (что приводит к дублированию огромного куска кода доктрины)?
А теперь вопрос .. Как обойти это (имея в виду, что я не прошу конкретное решение для простого случая, я прошу общее решение, которое может быть применено к большой базе кода, которая должна обслуживаться годамичтобы прийти - как вы можете видеть выше, у меня есть решения, но я не согласен с половиной заданий и хрупким кодом, если на самом деле нет другого пути)? Я ищу, может быть, пропущенную настройку, которая заставляет доктрину рассматривать целые числа как целые числа, а не как строки ... и тому подобное.