Вопрос

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.

Это было полезно?

Решение

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top