Использование Symfony и Doctrine с Oracle, не возвращающим правильный идентификатор при добавлении и увеличивающим последовательность на 2

#oracle #symfony #doctrine-orm #insert #sequence

#Oracle #symfony #doctrine-orm #вставить #последовательность

Вопрос:

Я использую Symfony с Doctrine для подключения к базе данных Oracle. Большинство вещей работает нормально, однако я только что добавил запись в базу данных и обнаружил, что получаю неправильный номер, и последовательность увеличивается на 2.

Итак, в сущности, для первичного ключа у меня есть:

 /**
 * @var integer
 *
 * @ORMColumn(name="PK", type="integer", nullable=false)
 * @ORMId
 * @ORMGeneratedValue(strategy="SEQUENCE")
 * @ORMSequenceGenerator(sequenceName="SEQ_GET_LOCATIONS_PK", allocationSize=1, initialValue=1)
 */
private $pk;
  

Когда я добавляю данные и возвращаю PK, у меня есть:

 $newMap = new Locations();
$newMap->setName($mapName);
$em = $this->getDoctrine()->getManager();
$em->persist($newMap);
$em->flush();
$mapId = $newMap->getPk();
  

В базе данных у меня есть триггер:

 create or replace TRIGGER insert_locations
Before Insert On "LOCATIONS" Referencing NEW AS NEW 
For Each Row  
  Begin
  SELECT SEQ_GET_LOCATIONS_PK.nextval into :new.pk from dual;
END;
  

и последовательность:

 CREATE SEQUENCE  "SCHEMA"."SEQ_GET_LOCATIONS_PK"  MINVALUE 14 MAXVALUE 99999999999999999999 INCREMENT BY 1 START WITH 109 CACHE 20 NOORDER  NOCYCLE ;
  

Когда я добавляю новый элемент в базу данных, скажем, если прошлый PK был равен 95, я бы ожидал, что новый будет равен 96, и ожидал бы, что это будет значение $ mapID . Однако я обнаружил, что в базе данных значение PK равно 97, хотя возвращаемое значение равно 96!

Мне интересно, связано ли это с тем, что триггер был оставлен там (он был там из прошлой версии программного обеспечения, отличной от symfony) или что-то в этом роде, но я удалил триггер и все еще проблема.

Это ошибка Doctrine?

Ответ №1:

Я нашел проблему для всех, у кого это будет в будущем. В итоге это стало триггером, я указал на другую таблицу, чтобы остановить ее запуск, но забыл скомпилировать ее, чтобы она все еще работала. Чтобы сохранить триггер там (для целей тестирования) и при этом все работало, измените триггер на:

 create or replace trigger insert_locations
Before Insert On "LOCATIONS" Referencing NEW AS NEW 
FOR EACH ROW  
  BEGIN
  IF :NEW.pk is NULL THEN
    SELECT SEQ_GET_LOCATIONS_PK.nextval INTO :NEW.pk FROM dual;
  END IF;
END;
  

Причина: когда я вставляю новую строку из Doctrine / Symfony, Doctrine просматривает последовательность и получает следующий номер. Когда он отправляет запрос Oracle для вставки, Oracle запускает триггер, который затем просматривает последовательность. Конечно, поскольку Doctrine уже получила последовательность, это приведет к повторному увеличению последовательности, предоставляя ей новый ключ, о котором Doctrine не знает.

Решение: либо удалите триггер (я хочу сохранить его, чтобы я мог вручную добавить элемент в базу данных для тестирования), либо добавьте проверку в триггер, чтобы заставить его заменять идентификатор только тогда, когда он не указан.