Skip to content

Loading…

DDC-1156: MappedSuperclass not allowed in the middle of an inheritance hierarchy #1757

Closed
doctrinebot opened this Issue · 4 comments

2 participants

@doctrinebot

Jira issue originally created by user holtkamp:

For a Class Table Inheritance mapping configuration, an intermediate MappedSuperclass causes a 'noInheritanceOnMappedSuperClass' mapping exception to be thrown by Doctrine\ORM\Mapping\ClassMetadataFactory::loadMetadata() (line 329). However, the MappedSuperclass only contains some simple properties and no inheritance configuration such as DiscriminatorMap or DiscriminatorColumn settings. The MappedSuperclass DOES extend the upper class in the hierarchy that contains this information using annotations, maybe this way it inherits this inheritance configuration.

The documentation state that a MappedSuperclass can occur in the middle of a inheritance hierarchy.
http://www.doctrine-project.org/docs/orm/2.0/en/reference/inheritance-mapping.html#mapped-superclasses

PS: this mapping seemed to be working fine for me using Doctrine 2.0.4 and Doctrine 2.0.5, further inspection showed that this is not the case. Persistence of an Entity fails, Doctrine wants to update a sequence of the persisted Entity, that does not exist as it is a Class Table Inheritance
PPS: this applies for the 2.1.0-BETA1 release, which is not yet available to create an issue for.

@doctrinebot

Comment created by @beberlei:

Fixed, why does this fail on 2.0.4/5? The code doesnt include that exception.

@doctrinebot

Comment created by holtkamp:

Adding the @MappedSuperclass annotation in the middle of an inheritance hierarchy does not throw an Exception anymore and the Schema Tool generates the proper SQL.

However the problem that was indicated for 2.0.4 and 2.0.5 in the first PS statement of my report remains. It seems that the @SequenceGenerator and in specific the 'sequenceName' setting is ignored for the childs / leafs of the inheritance hierarchy.

Configuration:

namespace Project\Entity\Payment;
/****
 * @Entity
 * @Table(schema="public", name="payment_method")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="discriminator", type="integer")
 * @DiscriminatorMap({
 * "1" = "Project\Entity\Payment\Method\PaymentCard\CreditCard",
 * "2" = "Project\Entity\Payment\Method\PaymentCard\DebitCard",
 * "3" = "Project\Entity\Payment\Method\ElectronicAccount"
 * })
abstract class Method
{
    /****
     * The Payment Method's identifier
     *
     * @var integer
     * @Column(name="id",type="integer",nullable=false)
     * @Id
     * @GeneratedValue(strategy="SEQUENCE")
     * @SequenceGenerator(sequenceName="payment*method_id*seq")
     */
    protected $_id;
}
namespace Project\Entity\Payment\Method;
/****
 * Project\Entity\Payment\Method\PaymentCard.php
 * Intermediate class that holds common information for PaymentCard Methods
 * No specific database table is required
 *
 * @MappedSuperclass
 */
abstract class PaymentCard extends Method{}

In the Entities that are defined in the discriminator map, we should leave the @Id annotation behind and to use the same sequence as that is used for the Project\Entity\Payment\Method Entity.

namespace Project\Entity\Payment\Method\PaymentCard;
/****
 * CreditCard specific class
 *
 * @Entity
 * @Table(schema="public", name="payment*method_payment_card_credit*card")
 */
class CreditCard extends PaymentCard
{

    /****
     * The Credit Card Payment Method identifier
     *
     * Note that no 'Entity-specific' sequence or auto-increment details should be defined, use the inheritance root entity's one
     * @link http://www.doctrine-project.org/docs/orm/2.0/en/reference/inheritance-mapping.html#class-table-inheritance
     * @var integer
     * @Column(name="id",type="integer",nullable=false)
     * @GeneratedValue(strategy="SEQUENCE")
     * @SequenceGenerator(sequenceName="payment*method_id*seq")
     */
    protected $_id;
}

However, Doctrine fails to persist a Project\Entity\Payment\Method\PaymentCard\CreditCard Entity as it tries to increase the value of the sequence of the CreditCard, which does not exist:

failed saving Entity, Project\Entity\Payment, SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "payment*method_payment_card_credit_card_id_seq" does not exist LINE 1: SELECT NEXTVAL('payment_method_payment_card_credit_card_id*s...

When I remove the @MappedSuperclass annotation from the intermediate PaymentCard class, this error does not occur and the proper sequence seems to be used.

@doctrinebot

Comment created by @beberlei:

Fixed

@doctrinebot

Issue was closed with resolution "Fixed"

@beberlei beberlei was assigned by doctrinebot
@doctrinebot doctrinebot added this to the 2.1 milestone
@doctrinebot doctrinebot closed this
@doctrinebot doctrinebot added the Bug label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.