使用mutil数据库时获取相关对象异常

时间:2019-01-01 12:50:37

标签: symfony doctrine-orm

当我将mutil数据库与相关对象一起使用时,找不到正确的表。  ta是acc数据库中的表名。  tb也是贸易数据库中的表名。 ta记录: 身份证名 1个名字

tb记录: 身份证名 1吨名称

        $em=$this->getDoctrine()->getRepository(ta::class,'customer');
        $ta=$em->find(2);//now ,it can fetch the data,and the data is right
        $tb=$ta->getTbTable();
        $szName=$tb->getName(); //i want to get the tb record,it will throw an exception :

............................................... 'acc.tb'不存在”

实际上,tb在贸易数据库中。

如何解决这些问题

<?php
    namespace AppBundle\Entity;
    use Doctrine\ORM\Mapping as ORM;
    use Doctrine\ORM\Mapping\PrePersist;
    use Doctrine\ORM\Mapping\PreUpdate;
    use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
    use Symfony\Component\Validator\Constraints as Assert;

    /**
     * @ORM\Table(name="ta")
     * @ORM\Entity(repositoryClass = "AppBundle\Entity\taRepository")
     * @ORM\HasLifecycleCallbacks()
     * @package AppBundle\Entity
     */
    class ta {
        /**
         * @ORM\Column(type="integer",unique=true)
         * @Assert\NotBlank(message="账号ID不能为空")
         * @ORM\Id
         */
        private $id;
        /**
         * @ORM\Column(type="string")
         */
        private $name;

        /**
         * @ORM\ManyToOne(targetEntity="AppBundle\EntityTrade\tb")
         * @ORM\JoinColumn(name="id",referencedColumnName="id")
         */
        private $tb_table;

    /**
     * Set id.
     *
     * @param int $id
     *
     * @return ta
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name.
     *
     * @param string $name
     *
     * @return ta
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set tbTable.
     *
     * @param \AppBundle\EntityTrade\tb|null $tbTable
     *
     * @return ta
     */
    public function setTbTable(\AppBundle\EntityTrade\tb $tbTable = null)
    {
        $this->tb_table = $tbTable;

        return $this;
    }

    /**
     * Get tbTable.
     *
     * @return \AppBundle\EntityTrade\tb|null
     */
    public function getTbTable()
    {
        return $this->tb_table;
    }
}

<?php
    namespace AppBundle\EntityTrade;
    use Doctrine\ORM\Mapping as ORM;
    use Doctrine\ORM\Mapping\PrePersist;
    use Doctrine\ORM\Mapping\PreUpdate;
    use Doctrine\ORM\Mapping\HasLifecycleCallbacks;
    use Symfony\Component\Validator\Constraints as Assert;

    /**
     * @ORM\Table(name="tb")
     * @ORM\Entity(repositoryClass = "AppBundle\EntityTrade\tbRepository")
     * @ORM\HasLifecycleCallbacks()
     * @package AppBundle\EntityTrade
     */
    class tb {
        /**
         * @ORM\Column(type="integer",unique=true)
         * @Assert\NotBlank(message="账号ID不能为空")
         * @ORM\Id
         */
        private $id;
        /**
         * @ORM\Column(type="string")
         */
        private $name;

    /**
     * Set id.
     *
     * @param int $id
     *
     * @return tb
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name.
     *
     * @param string $name
     *
     * @return tb
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
}

class defaultController{
  public function indexAction(){
             $em=$this->getDoctrine()->getRepository(ta::class,'customer');
            $ta=$em->find(2);
            $tb=$ta->getTbTable();
            $szName=$tb->getName();
 }
}

1 个答案:

答案 0 :(得分:0)

它不能以这种方式工作。 Doctrine的EntityManager仅支持单个数据库内实体的管理,因此将不会在tatb之间建立跨数据库关系。有关更多信息,请参阅Doctrine Bug跟踪程序中的this issue

但是,您的目标可以通过稍微不同的方式来实现。您不能在实体之间建立跨数据库关系,但是您当然可以存储将实体引用到不同数据库的ID。因此,您可以将所有跨数据库关系逻辑移动到存储库中。例如,假设每个数据库有2个EntityManager$accEm数据库的acc$tradeEm数据库的trade。请注意,您正在使用Symfony-可以将它们配置为DoctrineBundle配置,然后注入到服务中。

您将需要对代码进行一些更改:

ta.php ,我省略了大部分代码来表达需要进行的更改。

namespace AppBundle\Entity;

class ta
{
    /**
     * @ORM\Column(type="integer", nullable=true)
     * @var int
     */
    private $tb_table;  // Notice that it is not a reference anymore, but simple integer

    /**
     * Set tbTable.
     *
     * @param \AppBundle\EntityTrade\tb|null $tbTable
     *
     * @return ta
     */
    public function setTbTable(\AppBundle\EntityTrade\tb $tbTable = null)
    {
        // You can also consider updating this method to accept plain integers aswel
        $this->tb_table = $tbTable instanceof \AppBundle\EntityTrade\tb ? $tbTable->getId() : null;
        return $this;
    }

    /**
     * Get tbTable.
     *
     * @return int|null
     */
    public function getTbTable()
    {
        // Also notice that plain integer is returned, you may want to rename column and method names to reflect this change of column meaning
        return $this->tb_table;
    }
}

taRepository.php ,我也省略了大部分可能存在的代码

namespace AppBundle\Entity;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;

class taRepository extends EntityRepository {
    /**
     * @var EntityManager
     */
    private $tradeEm;

    /**
     * @param EntityManager $tradeEm
     */
    public function setTradeEntityManader(EntityManager $tradeEm)
    {
        // It is required to pass instance of EntityManager for "trade" database here. It should be done via Symfony services configuration, please refer Symfony documentation on this topic if needed
        $this->tradeEm = $tradeEm;
    }

    /**
     * @param ta $ta
     * @return \AppBundle\EntityTrade\tb|null
     */
    public function getTbTable(ta $ta) {
        // This method should be used instead of $ta::getTbTable()
        $tbId = $ta->getTbTable();
        if ($tbId === null) {
            return null;
        }
        return $this->tradeEm->find(\AppBundle\EntityTrade\tb::class, $tbId);
    }
}

defaultController.php

namespace AppBundle\Controller;

use Doctrine\ORM\EntityManager;

class defaultController
{
    /**
     * @var EntityManager
     */
    private $tradeEm;

    /**
     * @param EntityManager $tradeEm
     */
    public function __construct(EntityManager $tradeEm)
    {
        // Same as before, this should be instance of EntityManager for "trade" database
        $this->tradeEm = $tradeEm;
    }


    public function indexAction()
    {
        $em = $this->getDoctrine()->getRepository(ta::class, 'customer');
        $ta = $em->find(2);
        // Notice that we're not receiving "trade" database entity directly, but using corresponding EntityManager instead
        $tb = $this->tradeEm->getTbTable($ta);
        if ($tb !== null) {
            $szName = $tb->getName();
        }
    }
}