Доктрина: Многомерные Массивы в Доктрине 2

Я работаю с Symfony2 и Doctrine2, и у меня есть объект, который должен реализовать несколько массивов массивов. Единственное решение, которое я придумал, — это создать объект моста между моим основным объектом и объектом, на который он ссылается.

Так что это будет мой объект:

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

/**
* @ORM\OneToMany(targetEntity="CollectionOfObjectX", mappedBy="parent", cascade={"all"})
**/
private $collectionsOfObjectX;

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

... (Getters and Setters)

}

Это был бы мост между объектом и другим объектом

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

/**
* @ORM\ManyToOne(targetEntity="ObjectX",     inversedBy="collectionsOfObjectX", cascade={"all"})
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
**/
private $parent;

/**
* @ORM\ManyToMany(targetEntity="MyObject",     cascade={"all"})
* @ORM\JoinTable(
*      joinColumns={@ORM\JoinColumn(name="local_id", referencedColumnName="id")},
*      inverseJoinColumns={@ORM\JoinColumn(name="foreign_id", referencedColumnName="id")}
*      )
**/
private $items;

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

.... (Getters and Setters)

}

И это будет объект ссылки

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

... (Some Properties, Getters and Setters)
}

Таким образом, хотя это работает, для каждого возможного отношения между MyObject и любым другим объектом, на который он ссылается, требуется объект Bridge, что подразумевает много дублирующегося кода.

Есть ли способ лучше?

2

Решение

Доктрина 2 действительно не дает n-2-n абстрактных отношений. Объект A должен быть известным классом, и он должен ссылаться на Объект B (также известный класс).

Я бы предложил попробовать что-то вроде этого, чтобы обойти

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

/**
* @ORM\OneToMany(targetEntity="CollectionOfObjectXYZ", mappedBy="parent", cascade={"all"})
**/
private $collectionsOfObjectXYZ;

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

... (Getters and Setters)

}

Обратите внимание на отсутствующие аннотации

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

/**
* @ORM\ManyToOne(targetEntity="MyObject",     inversedBy="collectionsOfObjectXYZ", cascade={"all"})
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
**/
private $parent;

private $items;

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

public function addItem($item){
/** EDIT : since we store the relation in the final object (X Y Z), we don't need particular annotation here **/
$item->setCollectionOfObjectXYZ($this);
return $this;
}

.... (Getters and Setters)

}

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

/**
* @var CollectionOfObjectXYZ
*
* @ORM\ManyToOne(target="CollectionOfObjectXYZ", cascade={"persist"})
*/
private $colletion;

... (Some Properties, Getters and Setters)
}

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

/**
* @var CollectionOfObjectXYZ
*
* @ORM\ManyToOne(target="CollectionOfObjectXYZ", cascade={"persist"})
*/
private $colletion;

... (Some Properties, Getters and Setters)
}

Дайте мне знать, если это поможет.

1

Другие решения

Других решений пока нет …