Как отключить вызов секвенции в symfony?

verfaa

Профессор
Регистрация
29 Янв 2007
Сообщения
416
Реакции
49
Использую symfony 4.3.11
В сущности есть поле ID, которое использует секвенцию.

Код:
    /**
     * @var Id
     * @ORM\Column(type="work_articles_task_id")
     * @ORM\GeneratedValue(strategy="SEQUENCE")
     * @ORM\SequenceGenerator(sequenceName="work_articles_task_seq", initialValue=1)
     * @ORM\Id
     */
    private $id;

В репозитории к сущности я добавил метод для получения очередного ID из секвенции:
Код:
    public function nextId(): Id
    {
        return new Id((int)$this->connection->query("SELECT nextval('work_articles_task_id')")->fetchColumn());
    }
Проблема заключается в том, что после того, как я получаю очередной ID из секвенции, вызвав метод nextId(), доктрина также вызывает секвенцию, перезатирая полученный ID. Есть ли способ, чтобы доктрина не вызывала секвенцию автоматически?
 
Поменяй аннотации
@ORM\GeneratedValue(strategy="SEQUENCE")
@ORM\SequenceGenerator(sequenceName="work_articles_task_seq", initialValue=1)
на
@ORM\GeneratedValue(strategy="IDENTITY")

Она автоматом все подхватит.
 
Проблема может возникнуть из-за того, что Doctrine использует свои механизмы для работы с ID и автоматически генерирует значения при вставке новых записей. Если вы хотите использовать свою логику для генерации ID и избежать автоматической генерации Doctrine, вы можете попробовать следующий подход:

  1. Отключите генерацию ID Doctrine: Убедитесь, что вы отключили генерацию ID Doctrine, удалив аннотацию @GeneratedValue и связанные с ней настройки. В вашем коде это выглядит следующим образом:
    PHP:
    /**
    * [USER=62287]@var[/USER] Id
    * @ORM\Column(type="work_articles_task_id")
    * @ORM\Id
    */
    private $id;
  2. Не устанавливайте ID перед вставкой:Перед вставкой новой записи в базу данных не устанавливайте ID вручную. Doctrine должна взять на себя заботу об этом. Вместо этого, вы можете использовать ваш метод nextId() только тогда, когда вам нужно получить следующий доступный ID.
  3. Пример использования в коде:
    PHP:
    // Создание новой записи
    $entity = new YourEntity();
    
    // Получение следующего ID из вашего метода
    $nextId = $yourRepository->nextId();
    
    // Добавление ID в объект сущности
    $entity->setId($nextId);
    
    // Добавление сущности в EntityManager
    $entityManager->persist($entity);
    $entityManager->flush();
  4. Используйте прослойку:Если вы хотите сохранить автоматическую генерацию ID в Doctrine, а ваш метод nextId() использовать только при необходимости, вы можете реализовать прослойку (wrapper) вокруг вашей сущности, которая будет использовать ваш метод для установки ID только при определенных условиях.
    Пример:
    PHP:
    class YourEntityWrapper
    {
    private $entity;
    
    public function __construct(YourEntity $entity)
        {
    $this->entity = $entity;
        }
    
    public function getId()
        {
    return $this->entity->getId();
        }
    
    public function setId(Id $id)
        {
    $this->entity->setId($id);
        }
    }
    Таким образом, вы можете использовать YourEntityWrapper в случаях, когда вы хотите предотвратить автоматическую генерацию ID, и работать напрямую с вашей сущностью в остальных случаях.
 
Последнее редактирование модератором:
Отключить вызов секвенции (sequence) в Symfony можно, изменив настройки базы данных. Вам нужно будет создать файл конфигурации для вашего драйвера базы данных и указать параметр sequence_format = true или sequence_format = false в зависимости от того, хотите ли вы включить или отключить секвенцию.

Вот пример конфигурации для драйвера PdoPgSql:

doctrine:
dbal:
driver: pdo_pgsql
server_version: '12'
charset: UTF8
url: '%env(DATABASE_URL)%'

types:
json: Sonata\Doctrine\Types\JsonType
connections:
default:
mapping_types:
json: jsonb

sequences:
sequence_format: false
Вы можете изменить значение sequence_format на true или false, чтобы включить или отключить вызов секвенции.

Также стоит заметить, что отключение секвенций может привести к проблемам с уникальностью первичных ключей, поэтому перед применением изменений рекомендуется провести тестирование.
 
Назад
Сверху