2
votes

I'm using Symfony's entity classes in conjunction with Doctrine's ORM annotation to persist the values to the database. Most tables need a few standard fields, so I have created a base entity that all other entities can extend. According to the documentation this is called a MappedSuperClass: http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html

// src/Acme/Bundle/Entity/Base.php
namespace Acme\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\MappedSuperclass
 * @ORM\HasLifecycleCallbacks()
*/
class Base {

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

    // more values...

}

I then create multiple entities that extend this base:

// src/Acme/Bundle/Entity/View.php
namespace Acme\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;

View extends Entity\Base
{
     // entity definitions
}

Is this the best way to set default definitions for an entity? If you have better suggestions, let me know.

Next, when I generate entities via: php app/console doctrine:generate:entities Acme\Bundle

It works great the first time to create the getters and setters, but if I make changes to an entity and generate again, it gives an error like this:

Fatal error: Access level to Acme\Bundle\Entity\View::$id must be protected (as in class Acme\Bundle\Entity\Base) or weaker in /src/Acme/Bundle/Entity/View.php

This is happening because doctrine:generate:entities is importing the 'protected' variables from the MappedSuperClass into the extending entity as 'private'.

Others have complained about this error in other contexts without a solution: FOSUserBundle generate:entities does not work, Access level of fields too high https://github.com/FriendsOfSymfony/FOSUserBundle/issues/102

QUESTION: Is doctrine supposed to be importing the protected variables? And is it supposed to be setting them as "private"? Or is this just a known Symfony bug?

It seems like it should not import the protected variables since the @ORM definitions are in the MappedSuperClass already and those are not imported (and when I delete the imported private variables it works fine). But if it does import them, it should not be setting them as private...

I literally have to do a search and replace through all my entities to delete these. Every. Single. Time.

What is the suggested course of action here? If this is a bug, has someone reported this and what is the timeline for fixing? How should I search for this issue on github and report it if it's not reported?

Question 2: As long as this bug exists, is there a way to just generate the getters/setters on a Single Entity? e.g. php app/console doctrine:generate:entities Acme\Bundle\Entity\View (this doesn't work of course). If I could generate only one entity at a time, it would be less of a hassle deleting all the imported private variables across all my entities. [EDIT: I have answered this question below]

2

2 Answers

0
votes

The answer to #2 is, yes, you can generate entity getters/setters for just one single entity.

From the command line, if you type:

php app/console doctrine:generate:entities --help

You get a list of options. There you will see how to limit entities to bundle, single entity in a bundle, or an entire namespace:

You have to limit generation of entities:
* To a bundle: 
php app/console doctrine:generate:entities MyCustomBundle

* To a single entity:
php app/console doctrine:generate:entities MyCustomBundle:User
php app/console doctrine:generate:entities MyCustomBundle/Entity/User

* To a namespace
php app/console doctrine:generate:entities MyCustomBundle/Entity
0
votes

For the question 1, you need to redefine each primary key when entities are inherited.