Question

I have a problem with Doctrine, inheritance, and mapping. It's for a web game, that is based on city management. I won't copy all the code not because it's secret, but because I already have too much to fit in here.

The general design goes as follow :

Each Town have multiple Structure that are all relatively similar, then I decided to do a MappedSuperClass that go as follow

/**
* @ORM\MappedSuperclass
*/

class StructuresSuperClass{

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

/**
* @ORM\ManyToOne(targetEntity="BuildingType")
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $type;

/**
* @ORM\ManyToOne(targetEntity="Town", cascade={"persist"})
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $town;

In the structures there are Routes, Buildings and in Buildings there is a special on a TownCenter that have it's own Entity they go as follow :

Routes:

use Spagi\GameBundle\Entity\StructuresSuperClass as SSC;

/**
 * @ORM\Entity
 * @ORM\Table(name="Route")
 */
class Route extends SSC{

/**
* @ORM\OneToMany(targetEntity="RouteOrders", mappedBy="route",  cascade={"all"}, orphanRemoval=true)
*/
protected $orders;

/**
* @ORM\ManyToOne(targetEntity="Building", cascade={"persist", "remove"})
* @ORM\JoinColumn(onDelete="CASCADE")
*/
protected $origin;

/**
* @ORM\ManyToOne(targetEntity="Building", cascade={"persist", "remove"})
* @ORM\JoinColumn(onDelete="CASCADE")
*/
protected $destination;

Buildings:

use Spagi\GameBundle\Entity\StructuresSuperClass as SSC;

/**
* @ORM\Entity
* @ORM\Table(name="Building")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"TC" = "TownCenter", "Building" = "Building"})
*/

class Building extends SSC{

/**
 * @ORM\OneToOne(targetEntity="Inventory", cascade={"persist", "remove"})
 * @ORM\JoinColumn(onDelete="CASCADE")
 */
private $inventory;

/**
 * @ORM\Column(type="integer")
 */
private $radius;

/**
 * @ORM\Column(type="integer")
 */
private $theta;

And the TownCenter:

use Spagi\GameBundle\Entity\Building as Buildings;

/**
* @ORM\Entity
*/

class TownCenter extends Buildings{
public function __construct(){
    $this->setRadius(0);
    $this->setTheta(0);
    parent::__construct();
}

In the Town Entity I need to access each of these separatly so I created 3 OneToMany

/**
* @ORM\Entity
* @ORM\Table(name="Town")
*/

class Town{

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

/** SNIP **/

/**
 * @ORM\OneToMany(targetEntity="Building", mappedBy="town",  cascade={"all"}, orphanRemoval=true)
 */
protected $buildings;

/**
 * @ORM\OneToMany(targetEntity="TownCenter", mappedBy="town",  cascade={"all"}, orphanRemoval=true)
 */
protected $townCenter;

/**
 * @ORM\OneToMany(targetEntity="Route", mappedBy="town",  cascade={"all"}, orphanRemoval=true)
 */
protected $routes;

The problem is that I always receive a doctrine warning that my entities are invalid as follow

The field Spagi\GameBundle\Entity\Town#buildings is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity Spagi\GameBundle\Entity\Building#town does not contain the required 'inversedBy=buildings' attribute.
The field Spagi\GameBundle\Entity\Town#townCenter is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity Spagi\GameBundle\Entity\TownCenter#town does not contain the required 'inversedBy=townCenter' attribute.
The field Spagi\GameBundle\Entity\Town#routes is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity Spagi\GameBundle\Entity\Route#town does not contain the required 'inversedBy=routes' attribute.

From my understanding, this will lead to a performance degradation over time and with the growth of the DB. This relation Building#town, TownCenter#town and Route#town are all inherited from the same file. I can't write an inversedBy={'buildings','townCenter','routes'} ( well I haven't tried but I doubts it much ).

However I'd like to know if there is a solution to this issue other than defining the $town in each entity and thus missing the point with inheritance.

Était-ce utile?

La solution

You cannot do the mapping in your superclass. You have to map Town in every subclass.

So your Route would have town mapped with inversedBy="route", and your Building would have town mapped with inversedBy="building" etc.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top