Michael Villeneuve
Michael Villeneuve

Reputation: 4033

Doctrine query crashing

Very very weird. I have used this method from doctrine hundreds of times. I have a simple controller that takes an id as parameter. The query that Doctrine generates is wrong and crash.

/**
 * @Security("has_role('ROLE_ADMIN')")
 * @return Response
 */
public function editSellerAction($id)
{
    $em  = $this->getDoctrine()->getManager();
    $seller = $em->getRepository('SiteUserBundle:Seller')->find($id);

    // ...
    $form = $this->createForm(new SellerType(), $seller, array(
        'method' => 'POST'
    ));
    // ...
}

The query generated is the following

[2/2] DBALException: An exception occurred while executing 'SELECT t1.id AS id2, t1.username AS username3, t1.password AS password4, t1.firstname AS firstname5, t1.lastname AS lastname6 FROM seller t1 WHERE t0.id = ? LIMIT 1' with params ["2"]:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 't0.id' in 'where clause' +

The error thrown makes sense because it's looking at "WHERE t0.id" when it should be looking at "WHERE t1.id". I tried the query with t1 using phpmyadmin and it works.

Any idea what might cause this issue?

/**
 * Seller have access to their customer and are able to RW access to the customers
 *
 * @ORM\Table("seller")
 * @ORM\Entity
 * @author Michael Villeneuve
 */
class Seller extends User
{

    /**
     * @var array
     * 
     * @ORM\OneToMany(targetEntity="Customer", mappedBy="seller", cascade={"persist", "remove"})
     * @ORM\JoinColumn(name="seller_id", referencedColumnName="id")
     **/
    protected $customers; 

    /**
     * @var string
     *
     * @ORM\Column(name="firstname", type="string", length=255, nullable=false)
     */
    protected $firstname;

    /**
     * @var string
     *
     * @ORM\Column(name="lastname", type="string", length=255, nullable=false)
     */
    protected $lastname;

    // Other attributes and only getters/setter


/**
 *
 * @ORM\Entity
 */
class User implements UserInterface
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, unique=true)
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=64)
     */
    private $password;

I have 3 entities that extends the User (customer, admin and seller).

Upvotes: 5

Views: 4573

Answers (3)

Cerad
Cerad

Reputation: 48893

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

Read up a bit on mapped super classes: http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html. Basically, your abstract base user class cannot itself be an entity.

So take the @ORM\Entity line out of your User class. That is where the table 0 (t0) is coming from.

Upvotes: 10

Victor Bocharsky
Victor Bocharsky

Reputation: 12306

Try to add id field to the Seller entity instead of User

/**
 * Seller have access to their customer and are able to RW access to the customers
 *
 * @ORM\Table("seller")
 * @ORM\Entity
 */
class Seller extends User
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var array
     * 
     * @ORM\OneToMany(targetEntity="Customer", mappedBy="seller", cascade={"persist", "remove"})
     * @ORM\JoinColumn(name="seller_id", referencedColumnName="id")
     **/
    protected $customers; 

    /**
     * @var string
     *
     * @ORM\Column(name="firstname", type="string", length=255, nullable=false)
     */
    protected $firstname;

    /**
     * @var string
     *
     * @ORM\Column(name="lastname", type="string", length=255, nullable=false)
     */
    protected $lastname;

    // Other attributes and only getters/setter


/**
 *
 * @ORM\Entity
 * @author Michael Villeneuve<[email protected]>
 */
class User implements UserInterface
{

    /**
     * @ORM\Column(type="string", length=255, unique=true)
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=64)
     */
    private $password;

Upvotes: 0

ferdynator
ferdynator

Reputation: 6410

You have 2 options:

  • The first one is to create an abstract User entity and inherit all values from it. This is useful if you have many entities with the same behaviour. I e.g. like to create a BaseEntity with a ID field and some basic methods. All entities can extend this one and automatically have an ID. Cerad explained in his answer how this is done.
  • The second option are so called discriminator fields. Basically they allow you to have one User table and sub-tables for every extended entity. You can read about them in the official docs.

Which one you end up using is probably case dependent.

Upvotes: 2

Related Questions