Доктрина: Явное указание значения первичного ключа без изменения автоматического приращения

Существует таблица со многими столбцами, а также столбец первичного ключа «id», имеющий атрибут автоматического увеличения. База данных — mySQL.

В этот столбец вставляются два вида PHP-кода. 1.) Обычные запросы на вставку создаются в виде строки и выполняются путем подключения ADO к базе данных. В этом случае значение первичного ключа не предоставляется, поэтому используется значение автоматического увеличения таблицы.

2.) Существует класс сущности доктрины php symfony с основным полем, объявленным как

/**
     * @var int
     *
     * @ORM\Column(name = "id", type = "integer", nullable=false)
     * @ORM\Id
     */
    private $id;

Вставка использует метод persist диспетчера сущностей. Здесь при вставке значение идентификатора указано явно, который намного больше, чем значение автоинкремента столбца. Вот почему Generation_Type опущен в аннотациях.

Теперь предположим, что текущее значение auto_increment равно 10000. Я хочу, чтобы при выполнении первого сценария следующий идентификатор принимался как 1001, что и ожидается. А вот в случае выполнения второго сценария с явным id=2000 вставляет запись с 2000 но не меняет auto_increment на 2000. Все равно должно остаться на 1001.

Должен ли я вносить изменения в этот фрагмент кода?

$this->em->persist(obj);

Заранее спасибо.

почему ты хочешь сделать это? Похоже на ошибки, которые будет трудно найти через несколько месяцев

kuh-chan 29.03.2019 07:07

Итак, в системе два потока. Первый поток использует сценарий 1, который по-прежнему вставляет запросы, используя значение автоматического увеличения столбца id. Второй поток, который также является новым и использует сценарий 2, фактически является частью REST API. Клиент, который использует этот API, отправит идентификатор явно в полезной нагрузке, хотя этот идентификатор будет намного больше, чем текущее максимальное значение в столбце id. Я хочу, чтобы сценарий 1 по-прежнему использовал значение автоматического увеличения, а сценарий 2 использовал идентификатор, который он получает от своего клиента.

Dhruv Sharma 29.03.2019 09:13

Я понимаю ваш вариант использования, и на самом деле это можно сделать, манипулируя метаданными класса объекта во время выполнения, НО вам абсолютно не следует этого делать! И вот почему: значение автоинкремента в mySQL не сохраняется и будет определяться при запуске базы данных путем выбора максимального значения столбца id и установки следующего значения. Я не знаю, сможете ли вы каким-либо образом обойти это, но после того, как вы вставите запись с высоким идентификатором после следующего запуска, вы столкнетесь с проблемами.

Joe 29.03.2019 09:26

Дополнительная информация. Сброс поведения автоматического увеличения значения изменился в mySQL 5.8, поэтому в зависимости от вашей версии mysql вы можете это сделать. Вот дополнительная информация об этом изменении и возможных проблемах: benadel.com/blog/….

Joe 29.03.2019 09:34

Я использую версию mySQL 5.8. Поскольку вы сказали, что это можно сделать, манипулируя метаданными класса объекта, не могли бы вы предоставить пример кода, чтобы я мог изучить его и сравнить различные подходы к его обработке? Кстати, спасибо за блог, которым вы поделились.

Dhruv Sharma 29.03.2019 09:43

Я все еще думаю, что было бы лучше добавить столбец для «внешнего идентификатора». Было что-то похожее в старом проекте. «Это значение никогда не будет достигнуто», — сказали они. Угадай, что случилось...

kuh-chan 29.03.2019 11:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
6
2 246
1

Ответы 1

Если вам не нужно, чтобы ваша сущность Doctrine когда-либо использовала стратегию AUTO для установки значения идентификатора, вы должны просто иметь возможность использовать стратегию NONE

/**
 * @ORM\Column(type = "integer")
 * @ORM\Id()
 * @ORM\GeneratedValue(strategy = "NONE")
 */
private $id;

Дополнительную информацию о доступных стратегиях можно найти здесь: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/basic-mapping.html#identifier-generation-strategies

Если вам нужно, чтобы ваша сущность имела стратегию автоматического увеличения в обычном рабочем процессе, вы можете установить для нее значение AUTO и отключить ее в нужное время:

$metadata = $entityManager->getClassMetadata(get_class($entity));
$metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
$em->persist($entity);
$em->flush();

Общий отказ от ответственности: действуйте осторожно!

Я попробовал это. Проблема в том, что когда я указываю идентификатор явно, он успешно вставляет эту запись, но также изменяет значение автоматического увеличения этого столбца. Например, значение автоматического приращения равно 1000. И я вставляю запись с id = 2000. После вызова `$this->em->persist(obj); $this->em->flush(obj); ` значение автоматического увеличения изменяется на 2001, а это не то, что мне нужно.

Dhruv Sharma 29.03.2019 11:29

Я предполагаю, что эта часть происходит на уровне mysql без влияния доктрины. Хорошо, я не думаю, что вы предотвратите это, пока схема объявляет поле как auto_increment. Вероятно, это можно решить только путем запроса текущего значения, вставьте доктрину и выполните запрос, чтобы сбросить значение до того, что вы получили раньше. Однако произойдет ужасный сбой, если оба потока будут вставлены одновременно. В этот момент я бы переключился на совершенно другой подход и избавился бы от этого ужасного дизайна.

Joe 29.03.2019 11:42

Да, я согласен Этот подход может потерпеть неудачу во многих местах. Спасибо за объяснение.

Dhruv Sharma 29.03.2019 11:54

должны ли $entityManager и $em быть одной и той же переменной в вашем коде?

cgaldiolo 24.06.2019 14:03

@Джо, спасибо, чувак! Это работает для меня. В случаях, когда вам нужно, чтобы объект имел автоматически увеличивающийся идентификатор первичного ключа, но в некоторых случаях (например, автоматический импорт) вам необходимо установить идентификатор вручную, ЭТО ДОЛЖНО БЫТЬ ПРИНЯТО как правильный ответ. Спасибо чувак

Mirgen 30.03.2020 22:53

И, кстати, у меня не было проблемы с увеличением идентификатора +1 - я также использую MySQL - проблема должна быть где-то еще...

Mirgen 30.03.2020 22:55

Другие вопросы по теме