Моя сущность использует эту аннотацию для своего идентификатора:
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
Из чистой базы данных я импортирую существующие записи из более старой базы данных и пытаюсь сохранить те же идентификаторы. Затем при добавлении новых записей я хочу, чтобы MySQL как обычно автоматически увеличивал столбец идентификатора.
К сожалению, похоже, что Doctrine2 полностью игнорирует указанный идентификатор.
Новое решение
Согласно приведенным ниже рекомендациям, предпочтительным решением является следующее:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
Старое решение
Поскольку Doctrine опирается на ClassMetaData для определения стратегии генератора, ее необходимо изменить после управления сущностью в EntityManager:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$this->em->flush();
Я только что протестировал это в MySQL, и он работал, как ожидалось, то есть сущности с настраиваемым идентификатором сохранялись с этим идентификатором, в то время как объекты без указанного идентификатора использовали файл lastGeneratedId() + 1
.
источник
$metadata = $this->getEntityManager()->getClassMetaData(User::class); $metadata->setIdGenerator(new AssignedGenerator()); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
Ответы:
Хотя ваше решение отлично работает с MySQL, мне не удалось заставить его работать с PostgreSQL, поскольку оно основано на последовательности.
Я должен добавить эту строку, чтобы она работала идеально:
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
С уважением,
источник
$em->persist($entity)
.Возможно, какая доктрина изменилась, но теперь правильный путь:
источник
ClassMetadata
это интерфейс и поэтому не может иметь констант.$metadata::GENERATOR_TYPE_NONE
В случае, если сущность является частью наследования таблицы классов, вам необходимо изменить генератор идентификаторов в метаданных класса для обеих сущностей (сущность, которую вы сохраняете, и корневую сущность).
источник
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
ошибки. DownvotedНовое решение работает нормально только тогда, когда ВСЕ объекты имеют идентификатор перед вставкой. Когда одна сущность имеет идентификатор, а другая - нет - новое решение не работает.
Я использую эту функцию для импорта всех моих данных:
источник
Решение для Doctrine 2.5 и MySQL
«Новое решение» не работает с Doctrine 2.5 и MySQL. Вы должны использовать:
Однако я могу подтвердить это только для MySQL, потому что я еще не пробовал никаких других СУБД.
источник
Я создал библиотеку для установки будущих идентификаторов для сущностей Doctrine. Когда все идентификаторы в очереди израсходованы, он возвращается к исходной стратегии генерации идентификаторов, чтобы минимизировать влияние. Это должно быть легкое добавление для модульных тестов, чтобы не пришлось повторять подобный код.
источник
Вдохновленный работой Виллермена , я создал библиотеку tseho / doctrine-assign-identity, которая позволяет вручную назначать идентификаторы сущности Doctrine, даже если сущность использует состояния AUTO, SEQUENCE, IDENTITY или UUID.
Вы никогда не должны использовать его в производстве, но он действительно полезен для функциональных тестов.
Библиотека автоматически обнаружит сущности с назначенным идентификатором и заменит генератор только при необходимости. Библиотека будет использовать исходный генератор, если экземпляру не назначен идентификатор.
Замена генератора происходит в Doctrine EventListener, нет необходимости добавлять какой-либо дополнительный код в ваши фикстуры.
источник