#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 не знает.
Решение: либо удалите триггер (я хочу сохранить его, чтобы я мог вручную добавить элемент в базу данных для тестирования), либо добавьте проверку в триггер, чтобы заставить его заменять идентификатор только тогда, когда он не указан.