Description
Symfony version(s) affected
7.0.10+
Description
Hello,
I'm new in using Symfony/Doctrine and I've noticed that Messenger has a few issues with an Oracle database.
Our initialization of the Messenger environment is done manually by setting auto_setup: false
in messenger.yaml
and running the command bin/console messenger:setup-transports
in our CI/CD deployment pipeline.
Issue 1, with Symfony 7.0.10:
Versions:
Oracle DB 19c 19.0.0.0.0
PHP 8.3.10
PHP OCI 3.3.0 extension for PHP 8.3
Oracle Instaclient 19.24
Symfony 7.0.10
Symfony/Doctrine-messenger 7.0.9
The first time messenger:setup-transports
runs, all Messenger objects are well created, the table messenger_messages
, the 4 indexes, the messenger_messages_seq
sequence and the messenger_messages_ai_pk
trigger.
a) But when our CI/CD pipeline re-runs the messenger:setup-transports
command, there is every time an Oracle error : ORA-00955: Name is already used by an existing object
.
b) In addition, each time we request the generation of migration files with bin/console make:migration
command, we strangely obtain into files some instructions below concerning the messenger_messages_seq
sequence, which should not be present.
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('DROP SEQUENCE MESSENGER_MESSAGES_SEQ');
...
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SEQUENCE MESSENGER_MESSAGES_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1');
...
}
Issue 2, with Symfony 7.1 (7.1.11) same with 7.2:
Versions:
Oracle DB 19c 19.0.0.0.0
PHP 8.3.10
PHP OCI 3.3.0 extension for PHP 8.3
Oracle Instaclient 19.24
Symfony 7.1.11
Symfony/Doctrine-messenger 7.1.11
With these versions, each time messenger:setup-transports
runs, we always get the error ORA-00955: name is already used by an existing object
.
The messenger_messages_seq
sequence and the messenger_messages
table are created, but not the indexes nor the messenger_messages_ai_pk
trigger, so the Messenger environment is not functional.
How to reproduce
(see description)
Possible Solution
Solutions:
After investigations, here is what I applied to solve issue 1
Case a: With Oracle, don't leave the default table name messenger_messages
which is in lowercase, but force it to be uppercase table_name: 'MESSENGER_MESSAGES'
in messenger.yaml
configuration.
FYI, this table was created in uppercase in database by messenger:transports
and therefore as the schemaAssetsFilter
filter initialized in symfony/doctrine-messenger/Transport/Connection.php:setup()
is based on the default lowercase name, it doesn't work correctly if the table name is not forced to uppercase.
Case b: Simply exclude the MESSENGER_MESSAGES
table in the dbal
section of the doctrine.yaml
file with schema_filter: '~^(?!MESSENGER_MESSAGES)~i'
.
I thought the above actions would also fix issue 2, but not.
Upgrading to version 7.1 or 7.2 apparently causes a regression.
By tracing the processing of the function symfony/doctrine-messenger/Transport/Connection.php:updateSchema()
I see that the sequence MESSENGER_MESSAGES_seq
is created twice, as shown in the debug traces below:
>>> enter symfony/doctrine-messenger/Transport/Connection.php: updateSchema()
>>> foreach ($schemaDiff->getCreatedSequences() as $sequence)
SQL 0: CREATE SEQUENCE MESSENGER_MESSAGES_seq START WITH 1 MINVALUE 1 INCREMENT BY 1
>>> foreach ($platform->getCreateTablesSQL($schemaDiff->getCreatedTables()) as $sql)
SQL 1: CREATE TABLE MESSENGER_MESSAGES (id NUMBER(20) DEFAULT MESSENGER_MESSAGES_seq.nextval NOT NULL, body CLOB NOT NULL, headers CLOB NOT NULL, queue_name VARCHAR2(190) NOT NULL, created_at TIMESTAMP(0) NOT NULL, available_at TIMESTAMP(0) NOT NULL, delivered_at TIMESTAMP(0) DEFAULT NULL NULL, PRIMARY KEY(id))
SQL 2: DECLARE
constraints_Count NUMBER;
BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'MESSENGER_MESSAGES'
AND CONSTRAINT_TYPE = 'P';
IF constraints_Count = 0 OR constraints_Count = '' THEN
EXECUTE IMMEDIATE 'ALTER TABLE MESSENGER_MESSAGES ADD CONSTRAINT MESSENGER_MESSAGES_AI_PK PRIMARY KEY (ID)';
END IF;
END;
SQL 3: CREATE SEQUENCE MESSENGER_MESSAGES_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1
In SetupTransportsCommand.php line 79:
An error occurred while setting up the "async" transport: An exception occurred while executing a query: ORA-00955: name is already used by an existing object
In ExceptionConverter.php line 65:
An exception occurred while executing a query: ORA-00955: name is already used by an existing object
In Error.php line 21:
ORA-00955: name is already used by an existing object
I guess it's the add of the code below to the function symfony/doctrine-messenger/Transport/Connection.php:addTableToSchema()
that causes this issue.
What do you think?
// We need to create a sequence for Oracle and set the id column to get the correct nextval
if ($this->driverConnection->getDatabasePlatform() instanceof OraclePlatform) {
$idColumn->setDefault($this->configuration['table_name'].self::ORACLE_SEQUENCES_SUFFIX.'.nextval');
$schema->createSequence($this->configuration['table_name'].self::ORACLE_SEQUENCES_SUFFIX);
}
And so, is there any workaround solution ?
Thank you for your help.
Additional Context
No response