У меня есть 2 объекта.
простая логика заключается в том, что у пользователя много адресов доставки, поэтому в будущем он сможет выбрать один из них для своих доставки.
первый объект, Direccion (адрес).
<?php
use Doctrine\ORM\Mapping as ORM;
/**
* Direccion
*
* @ORM\Table(name="direccion", indexes={@ORM\Index(name="id_usuario",
columns={"id_usuario"})})
* @ORM\Entity
*/
class Direccion
{
/**
* @var string
*
* @ORM\Column(name="Calle", type="string", length=100, nullable=false)
*/
private $calle;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \Usuario
*
* @ORM\ManyToOne(targetEntity="Usuario", inversedBy="direcciones", fetch="EAGER")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="id_usuario", referencedColumnName="id" )
* })
*/
private $idUsuario;
/**
* Set calle
*
* @param string $calle
* @return Direccion
*/
public function setCalle($calle)
{
$this->calle = $calle;
return $this;
}
/**
* Get calle
*
* @return string
*/
public function getCalle()
{
return $this->calle;
}
/**
* Set idUsuario
*
* @param \Usuario $idUsuario
* @return Direccion
*/
public function setIdUsuario(\Usuario $idUsuario = null)
{
$this->idUsuario = $idUsuario;
return $this;
}
/**
* Get idUsuario
*
* @return \Usuario
*/
public function getIdUsuario()
{
return $this->idUsuario;
}
}
и второй объект - Usuario (Пользователь)
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Usuario
*
* @ORM\Table(name="usuario")
* @ORM\Entity
*/
class Usuario
{
/**
* @var string
*
* @ORM\Column(name="nombre", type="string", length=255, nullable=true)
*/
private $nombre;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="Direccion", mappedBy="id_usuario", cascade={"persist"})
*/
private $direcciones;
public function __construct()
{
$this->direcciones = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set nombre
*
* @param string $nombre
* @return Usuario
*/
public function setNombre($nombre)
{
$this->nombre = $nombre;
return $this;
}
/**
* Get nombre
*
* @return string
*/
public function getNombre()
{
return $this->nombre;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
public function getDirecciones()
{
return $this->direcciones;
}
public function setDirecciones($direcciones)
{
$this->direcciones = $direcciones;
return $this;
}
}
я уже читал много блогов и подобных вопросов, но я не могу получить свойство $ direcciones, увлажненное или заполненное соответствующими данными, когда я пытаюсь добиться этого на обратной стороне отношения (OneToMany), с $usuario-> getDirecciones();
Я работаю с этим кодом в архитектуре, отличной от MVC, до сих пор все работает как шарм при создании и обновлении через DAO, в котором используются предложения Doctrine, поэтому я знаю, что в конечных точках (обновление, создание, сохранение и flush, получение данных с помощью find, findBy и т.д.), все работает нормально.
когда я пытаюсь заполнить вызов ArrayCollection с уровня Service, где я использую оба класса (Usuario-InverseSide и Direccion-OwnerSide), ничего не происходит, свойство $ direcciones arrayCollection на экземпляре Usuario не получает ничего, даже когда я пытался установить fetch = "EAGER" в аннотациях.
для остальных данных или свойств все работает нормально, все остальные атрибуты пользователя заполняются просто отлично.
По какой-то причине аннотации не рассматриваются, не знаю почему. Я потратил несколько дней, пытаясь понять, как реализовать этот способ доступа к связанным данным, не хотел использовать DQL, но на данный момент я думаю, что я возьму эту дорогу.
Я попробовал что-то жестко закодированное для тестирования, и результат тот же, $ direcciones не получает его данных. Очевидно, что уже отброшены, что для точного идентификатора для Usuario (пользователя) установлены связанные с ним настройки (адрес).
$usuario = $this->usuarioDAO->find(20);
$direcciones = $usuario->getDirecciones();
var_dump($direcciones);
return $usuario;
отношение определялось только с помощью FK, называемого id_usuario на Direccion, в таблице mysql InnoDb.
не знаю, должен ли я устанавливать что-то еще в таблице Usuario. или если что-то не так в том, как я храню объекты в моем проекте.
пожалуйста, помогите мне, любая рекомендация будет оценена по достоинству.
Доктрина 2, hwo действительно получает данные с обратной стороны (многие к одному)
Я решил это.
случается, что по какой-то причине аннотации php фактически не читались или, по-другому, не говорили об этом, он сначала слушал аннотации XML, поэтому я помещал предложение xml на обратную сторону отношения (usuario) внутри теги
<one-to-many field="direcciones" target-entity="Direccion" mapped-by="idUsuario" />
и это сработало, теперь я получил польский результат данных консультации, поэтому я могу отправить более чистый/более четкий объект в интерфейс.
Если ваше двунаправленное сопоставление между Direccion
и Usuaro
является правильным, вам необходимо использовать методы Usuaro
с обеих сторон.
И другое: при использовании ArrayCollection
проще (возможно, единственный способ) добавлять элементы один за другим.
Поэтому вместо setDirecciones()
вы добавляете этот метод в класс Usuario
:
public function addDireccion(Direccion $direccion) {
$direccion->setIdUsuario($this);
$this->direcciones->add($direccion);
}
Надеюсь, это поможет.
И было бы лучше назвать его $usuario
setUsuario
и setUsuario
вместо od setIdUsuario
потому что вы работаете с объектами, а PHP не должен беспокоиться о фактических именах полей базы данных (чтобы сказать так).