Odyss3us
Odyss3us

Reputation: 6635

Doctrine 2 - Error Persisting Subclass of Class Table Inheritance Mapping Strategy

I've implement Class Table Inheritance using Doctrine 2 in my Symfony 3 project, so as to have one base profile table, that houses both employee and company profiles.

When trying to persist a sub class (EmployeeProfile) of the mapped super class (AbstractProfile), I get the following error:

An exception occurred while executing 'INSERT INTO profile (id) VALUES (?)' with params [27, 10, 85, \"employee\"]:\n\nSQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

I'm not entirely sure what's going wrong, and why Doctrine is generating a query that's entirely ignoring the AbstractProfile's properties. Initially I thought it was due to said properties not being visible to the children, but even after setting the properties to protected, the error remains.

How exactly can I fix this, or am I trying to fit a square peg into a round hole by not using this functionality for what is was intended?

profile DB Table:

+------------+--------------+------+-----+-------------------+----------------+
| Field      | Type         | Null | Key | Default           | Extra          |
+------------+--------------+------+-----+-------------------+----------------+
| id         | int(11)      | NO   | PRI | NULL              | auto_increment |
| user_id    | int(11)      | NO   |     | NULL              |                |
| type       | varchar(100) | NO   |     | NULL              |                |
| status     | int(11)      | NO   |     | NULL              |                |
| created_at | datetime     | NO   |     | CURRENT_TIMESTAMP |                |
| updated_at | datetime     | NO   |     | CURRENT_TIMESTAMP |                |
+------------+--------------+------+-----+-------------------+----------------+

AbstractProfile Super Class:

/**
 * AbstractProfile
 *
 * @ORM\Table(name="profile")
 * @ORM\Entity(repositoryClass="ProfileBundle\Repository\ProfileRepository")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({
 *     "employee" = "EmployeeProfile",
 *     "company" = "CompanyProfile"
 * })
 */
abstract class AbstractProfile
{

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var int
     *
     * @ORM\Column(name="status", type="integer")
     */
    protected $status;

    /**
     * @ORM\OneToOne(targetEntity="User", inversedBy="profile")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

    //... Getters, setters and all the rest
}

EmployeeProfile Sub Entity:

<?php

/**
 * EmployeeProfile
 *
 * @ORM\Table(name="profile")
 * @ORM\Entity
 */
class EmployeeProfile extends AbstractProfile
{
    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Skill", inversedBy="profiles")
     * @ORM\JoinTable(name="profile_skills",
     *      joinColumns={@ORM\JoinColumn(name="profile_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="skill_id", referencedColumnName="id", unique=true)}
     *      )
     */
    private $skills;

    public function __construct()
    {
        $this->skills = new ArrayCollection();
    }

    //... Getters, setters and all the rest
}

CompanyProfile Sub Entity:

<?php

/**
 * CompanyProfile
 *
 * @ORM\Table(name="profile")
 * @ORM\Entity
 */
class CompanyProfile extends AbstractProfile
{    
    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Event", inversedBy="profiles")
     * @ORM\JoinTable(name="profile_events",
     *      joinColumns={@ORM\JoinColumn(name="profile_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="event_id", referencedColumnName="id", unique=true)}
     *      )
     */
    private $events;

    public function __construct()
    {
        $this->events = new ArrayCollection();
    }

    //... Getters, setters and all the rest
}

Upvotes: 0

Views: 344

Answers (1)

No&#233;mi Sala&#252;n
No&#233;mi Sala&#252;n

Reputation: 5036

It looks like you are trying to use @ORM\InheritanceType("JOINED") with a single table. You use @ORM\Table(name="profile") in your 3 entities.

The result is that Doctrine don't know what to do with your entities.

You could try replacing @ORM\InheritanceType("JOINED") by @ORM\InheritanceType("SINGLE_TABLE").

Upvotes: 1

Related Questions