【问题标题】:doctrine2 , retrieve associated data from inverse side学说2,从反面检索相关数据
【发布时间】:2017-12-13 22:39:11
【问题描述】:

我有 2 个实体。

简单的逻辑是一个用户有很多送货地址,所以他将来可以选择其中一个送货。

第一个实体,方向(地址)。

<?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;
    }



}

我已经阅读了许多博客和类似的问题,但是当我尝试在关系的反面 (OneToMany) 上使用 $ usuario->getDirecciones();

我正在非 MVC 架构中使用此代码,到目前为止,一切都像魅力一样通过使用 Doctrine 语句的 DAO 进行创建和更新,所以我知道在结束点(更新、创建,持久化和刷新,使用 find、findBy 等检索数据),一切正常。

当我尝试从使用两个类(Usuario-InverseSide 和 Direccion-OwnerSide)的服务层填充 ArrayCollection 调用时,没有任何反应,Usuario 实例上的 $direcciones arrayCollection 属性不会获取任何内容,即使当我尝试在注释上建立 fetch="EAGER"。

对于其余的数据或属性,一切正常,用户的所有其他属性都得到了很好的填充。

由于某种原因,注释没有被考虑,不知道为什么。 我花了几天时间试图弄清楚如何完成这种访问关联数据的方式,不想使用 DQL,但在这一点上我想我会走这条路。

我尝试了一些硬编码来测试,结果是一样的,$direcciones 没有得到他的数据。显然已经被丢弃了,Usuario(user) 的确切 ID 已经设置了他的相关 direcciones(address) .

$usuario = $this->usuarioDAO->find(20);
        $direcciones = $usuario->getDirecciones();
        var_dump($direcciones);
        return $usuario;

关系仅在 mysql InnoDb 表上的 Direccion 上使用名为 id_usuario 的 FK 定义。

不知道我是否应该在 Usuario 桌子上设置其他东西。 或者如果我在项目中存储实体的方式有问题。

请帮助我,任何建议将不胜感激。

doctrine 2, hwo do get data from the inverse side (many to one)

【问题讨论】:

  • 尝试将 mappedBy="id_usuario" 更改为 mappedBy="idUsuario"
  • 感谢您的回答,我已经尝试过了,知道 Direccion 实体上的属性称为 idUsuario,但完成更改后仍然无法正常工作。我将尝试更改数据库表上列的名称。
  • 尝试遍历你的集合 foreach ($direcciones as $dir) { var_dump($dir); }
  • 如果我只 var 转储用户结果是,(我将恢复到 2 或 3 个属性来解决 post.length 问题){}object(Usuario)#109 (13) { ["rut ":"Usuario":private]=> 字符串(10) "17738715-0" ["nombre":"Usuario":private]=> NULL ["perfil":"Usuario":private]=> 字符串(7) "usuario" ["telefono":"Usuario":private]=> string(7) "7346534" ["id":"Usuario":private]=> int(20) ["direcciones":"Usuario":private ]=> NULL } 所以,已经找到的用户没有得到他的 $direcciones 填充,由于某种原因,学说没有倾听或考虑关系。
  • 所以为了获得更多细节和更少的时间观看 ["direcciones":"Usuario":private]=> NULL } 当我尝试迭代时,会出现这个警告,当你不传递数组时会发生这种情况或者在这种情况下,一个定义良好的 ArrayCollection ($direcciones 在其实体上以这种方式初始化)。 警告:在 119 行的 C:\Apache24\htdocs\doctrine2tutorial\src\service\usuarioService.php 中为 foreach() 提供的参数无效

标签: mysql doctrine-orm one-to-many many-to-one hydration


【解决方案1】:

前提是你DireccionUsuaro之间的双向映射是正确的,你需要两边都使用setter方法。

另外,在使用ArrayCollection 时,更简单(也许是唯一的方法)是逐个添加元素。

因此,您可以将此方法添加到 Usuario 类中,而不是 setDirecciones()

public function addDireccion(Direccion $direccion) {
    $direccion->setIdUsuario($this);
    $this->direcciones->add($direccion);
}

希望对您有所帮助。

而且,最好将其命名为 $usuariosetUsuario 而不是 setIdUsuario,因为您使用对象并且 PHP 不应该关心实际的数据库字段名称(这样说)。

【讨论】:

  • 谢谢,这将很有用,因为我已经实现了让它带来正确的数据。碰巧由于某种原因,实际上并没有读取 php 注释,或者以不同的方式说它,它首先在听 XML 注释,所以我把 xml 语句放在了关系的反面(usuario)里面 标签 并且它有效,现在我得到了咨询的数据结果所以我可以向前端发送一个更干净/更清晰的对象。
【解决方案2】:

我解决了。

由于某种原因,实际上并没有读取 php 注释,或者换一种说法,它首先是在听 XML 注释,所以我把 xml 语句放在了关系的反面( usuario) 在标签内

<one-to-many field="direcciones" target-entity="Direccion" mapped-by="idUsuario" />

它成功了,现在我对咨询的数据结果进行了润色,这样我就可以向前端发送一个更清晰/更清晰的对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多