orm: IDENTITY identifier strategy for PostgreSQL breaks when inherited from MappedSuperclass
BC Break Report
Q | A |
---|---|
BC Break | yes |
Version | 2.16.0 |
Summary
Persisting an @Entity
which has it’s @Id
defined in it’s parent (@MappedSuperclass
) with IDENTITY
generator strategy on PostgreSQL platform.
It seems that the breaking change occured in this PR https://github.com/doctrine/orm/pull/10455, specifically changes in ClassMetadataFactory
that removed the condtion of $rootEntityFound
for calling inheritIdGeneratorMapping()
Previous behavior
In version 2.15.5
the IdentityGenerator
used to retrieve inserted id came from the Entity itself with $sequenceName
matching the schema. So the value was retrieved from the correct sequence.
Current behavior
Now the IdentityGenerator
used to retrieve inserted id comes from the parent @MappedSuperclass
and $sequenceName
is wrong (name of parent class + sequence suffix) and non-existent in schema, so a PostgreSQL error about relation not existing is thrown.
How to reproduce
E.g. (irrelevant code and domain-specific terminology is ommited):
/**
* @ORM\MappedSuperclass
*/
abstract class AbstractTaskOperatorHistoryRecord
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private ?int $id = null;
}
/**
* @ORM\Entity()
* @ORM\Table(name="foo_bar_task_operator_history")
*/
class FooBarTaskOperatorHistoryRecord extends AbstractTaskOperatorHistoryRecord
{
}
$this->_em->persist(new FooBarTaskOperatorHistoryRecord());
$this->_em->flush();
The PostgreSQL sequence used by id
column in foo_bar_task_operator_history
table is foo_bar_task_operator_history_id_seq
.
The sequence used to retrieve inserted id was foo_bar_task_operator_history_id_seq
before the breaking change. Now it is trying to get the value from abstracttaskoperatorhistoryrecord_id_seq
which obviously does not and should not exist. The error thrown is
PDOException
SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "abstracttaskoperatorhistoryrecord_id_seq" does not exist
About this issue
- Original URL
- State: closed
- Created 10 months ago
- Reactions: 2
- Comments: 18 (10 by maintainers)
Commits related to this issue
- Fix `@SequenceGeneratorDefinition` inheritance, take 1 #10927 reported that #10455 broke the way how the default `@SequenceGeneratorDefinition` is created and inherited by subclasses for ID columns ... — committed to doctrine/orm by mpdude 8 months ago
- Fix `@SequenceGeneratorDefinition` inheritance, take 2 This is an alternative implementation to #11050. The difference is that with this PR here, once `@SequenceGeneratorDefinition` is used in an inh... — committed to mpdude/doctrine2 by mpdude 8 months ago
- Fix `@SequenceGeneratorDefinition` inheritance, take 2 This is an alternative implementation to #11050. The difference is that with this PR here, once `@SequenceGeneratorDefinition` is used in an inh... — committed to mpdude/doctrine2 by mpdude 8 months ago
- Fix `@SequenceGeneratorDefinition` inheritance, take 1 (#11050) #10927 reported that #10455 broke the way how the default `@SequenceGeneratorDefinition` is created and inherited by subclasses for ID ... — committed to doctrine/orm by mpdude 6 months ago
@Arkemlar please stay polite, no one wants to hear you complain like that, especially not people providing you with free software .
@Chris53897 @mpdude indeed, both solutions have resolved the issue
I see two ways how this could be fixed.
The first one is in #11050. It reverts the way inheritance works for
@SequenceGeneratorDefinition
and mapped superclasses. But, with this change one cannot define@SequenceGeneratorDefinition
on mapped superclasses and expect it to be inherited by child entity classes - at least not when using the newreportFieldsWhereDeclared
mapping driver mode.The second approach is in #11052. It will recognize when an explicit
@SequenceGeneratorDefinition
is used and pass that one on unchanged to child classes (= all use the same sequence name). Otherwise, the default one will be generated for every single class, so the sequence name is based on the table name.@DemoniacDeath did you opt into the new „report fields where declared“ setting?