MappingException: Class « Y » sub class of « X » is not a valid entity or mapped super class.

Voilà pour moi l’occasion de poster une petite solution concernant un problème que j’ai récemment rencontrer.

Héritable à partir d’une classe mappé

Dans mon cas, je disposais d’une première classe déjà mappée dans mon application Symfony2. Pour de multiples raisons, dans l’application que je développe, j’ai plusieurs contraintes qui m’obligent à utiliser cette classe de deux manières différentes.

Dans mon premier cas, j’utilise cette classe normalement alors que dans un second cas, je dois mettre en place une autre classe reprenant l’intégralité des données de ma première classe pour créer une entité permettant de s’authentifier dans mon application.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * @ORM\Table(name="User")
 * @ORM\Entity()
 */
class User
{
    /**
     * @var string
     *
     * @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
     */
    private $id;
}

Dans ma classe qui doit hérité de la première, voici comment j’ai procéder initialement.

1
2
3
4
5
class User2 extends User implements UserInterface, \Serializable
{
//my others methods
}

Quand on tente d’accéder à une page ou bien de lancer une commande depuis la console, voici l’erreur levée.

1
MappingException: Class "Namespace\MyBundle\Entity\User2" sub class of "Namespace\MyBundle\Entity\User" is not a valid entity or mapped super class.

MappedSuperClass, la solution

La solution est simple mais il faut avouer que la documentation de Doctrine met peu en avant cette fonctionnalité.

Lorsque vous héritez d’une classe déjà mappé vous ne réutiliser pas les données de mappage. Cela dit, vous devez spécifier les données de mapping. On utilise alors l’attribut MappedSuperClass pour indiquer à l’entité qui hérite qu’on souhaite utiliser les données de mappage appliquées aux attributs.

ATTENTION, cette option n’importe que les données des attributs et pas les données de l’entité au niveau global.

1
2
3
4
5
6
7
8
9
/**
* @ORM\MappedSuperclass
* @ORM\Table(name="User")
* @ORM\Entity()
*/
class User2 extends User implements UserInterface, \Serializable
{
//my others methods …
}

J’espère que cette solution vous aura fait gagner du temps car il m’a fallut un peu de temps pour trouver mon erreur.