Search code examples
phpsqldoctrine-ormdoctrinemappedsuperclass

Doctrine - OneToOne relationship not working with extends MappedSuperclass


I try to use @MappedSuperclass. It works well for simple variable (int, string...) and OneToMany/ManyToOne relationship. But OneToOne relationship doesn't work.

I have two MappedSuperclass with OneToOne relationship : _SiteUser

/**
 * @MappedSuperclass _SiteUser
 *
 * @ORM\Entity(repositoryClass="_SiteModule\_Repository\_SiteUserRepository")
 * @ORM\Table(name="site_users")
 */
class _SiteUser
{
    /**
     * @var int
     * @Groups("id")
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     * @Groups({"username"})
     *
     * @ORM\Column(name="username", type="string", length=255, unique=true)
     */
    protected $username;

    /**
     * @var string
     * @Groups({"password"})
     *
     * @ORM\Column(name="password", type="string", length=255)
     */
    protected $password;

    /**
     * @var _SiteUserTo
     *
     * @ORM\OneToOne(targetEntity="_SiteModule\_Entity\_SiteUserTo", mappedBy="user")
     * @Gedmo\Versioned()
     */
    protected $user_to;

_SiteUserTo

/**
 * @MappedSuperclass _SiteUserTo
 *
 * @ORM\Entity(repositoryClass="_SiteModule\_Repository\_SiteUserToRepository")
 * @ORM\Table(name="users_to")
 */
class _SiteUserTo
{
    /**
     * @var int
     * @Groups("id")
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var _SiteUser
     *
     * @ORM\OneToOne(targetEntity="_SiteModule\_Entity\_SiteUser", inversedBy="user_to")
     * @JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

And this is my 2 class who extends these MappedSuperclass : SiteUser

/**
 * SiteUser
 *
 * @ORM\Entity(repositoryClass="SiteModule\Repository\SiteUserRepository")
 * @ORM\Table(name="site_users")
*/
class SiteUser extends _SiteUser
{
}

SiteUserTo

/**
 * SiteUserTo
 *
 * @ORM\Entity(repositoryClass="SiteModule\Repository\SiteUserToRepository")
 * @ORM\Table(name="users_to")
*/
class SiteUserTo extends _SiteUserTo
{
}

When I generate entities from my MappedSuperclass (_SiteUser and _SiteUserTo), I got well a table named "users_to" with id and user_id. But when I generate entities from my others classes (SiteUser and SiteUserTo), it creates the table "users_to" with only id field. I don't know why...

If I update my SiteUser Class like this :

/**
 * Class SiteUser
 *
 * @ORM\Entity(repositoryClass="SiteModule\Repository\SiteUserRepository")
 * @ORM\Table(name="site_users")
*/
class SiteUser extends _SiteUser
{
    /**
     * @var boolean
     *
     * @ORM\Column(name="test", type="boolean")
     */
    protected $test;

    /**
     * @var SiteUserTo
     *
     * @ORM\OneToOne(targetEntity="SiteModule\Entity\SiteUserTo", mappedBy="user")
     */
    protected $user_to;
}

And SiteUserTo like this :

/**
 * Class SiteUserTo
 *
 * @ORM\Entity(repositoryClass="SiteModule\Repository\SiteUserToRepository")
 * @ORM\Table(name="users_to")
*/
class SiteUserTo extends _SiteUserTo
{
    /**
     * @var boolean
     *
     * @ORM\Column(name="test", type="boolean")
     */
    protected $test;

    /**
     * @var SiteUser
     *
     * @ORM\OneToOne(targetEntity="SiteModule\Entity\SiteUser", inversedBy="user_to")
     * @JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

}

I got the same problem, no field user_id in table users_to. But the field "test" is well created in the table site_users and in the table users_to...


Solution

  • A mapped superclass cannot be an entity, it is not query-able and persistent relationships defined by a mapped superclass must be unidirectional (with an owning side only). This means that One-To-Many associations are not possible on a mapped superclass at all. Furthermore Many-To-Many associations are only possible if the mapped superclass is only used in exactly one entity at the moment. For further support of inheritance, the single or joined table inheritance features have to be used.

    Simply said you can not have @MappedSuperClass and @ORM\Entity annotations at the same time, hence the unexpected results

    https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/inheritance-mapping.html