使用多数据库时发生获取相关对象异常



当我使用带有条令的多数据库来处理相关对象时,它无法以正确的方式找到表。ta是acc数据库中的表名。tb也是贸易数据库中的表名。ta记录:id名称1 ta名称

结核病记录:id名称1 tb名称

$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'不存在">

实际上,结核病在贸易数据库中。

如何解决这些问题

<?php
namespace AppBundleEntity;
use DoctrineORMMapping as ORM;
use DoctrineORMMappingPrePersist;
use DoctrineORMMappingPreUpdate;
use DoctrineORMMappingHasLifecycleCallbacks;
use SymfonyComponentValidatorConstraints as Assert;
/**
* @ORMTable(name="ta")
* @ORMEntity(repositoryClass = "AppBundleEntitytaRepository")
* @ORMHasLifecycleCallbacks()
* @package AppBundleEntity
*/
class ta {
/**
* @ORMColumn(type="integer",unique=true)
* @AssertNotBlank(message="账号ID不能为空")
* @ORMId
*/
private $id;
/**
* @ORMColumn(type="string")
*/
private $name;
/**
* @ORMManyToOne(targetEntity="AppBundleEntityTradetb")
* @ORMJoinColumn(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 AppBundleEntityTradetb|null $tbTable
*
* @return ta
*/
public function setTbTable(AppBundleEntityTradetb $tbTable = null)
{
$this->tb_table = $tbTable;
return $this;
}
/**
* Get tbTable.
*
* @return AppBundleEntityTradetb|null
*/
public function getTbTable()
{
return $this->tb_table;
}
}
<?php
namespace AppBundleEntityTrade;
use DoctrineORMMapping as ORM;
use DoctrineORMMappingPrePersist;
use DoctrineORMMappingPreUpdate;
use DoctrineORMMappingHasLifecycleCallbacks;
use SymfonyComponentValidatorConstraints as Assert;
/**
* @ORMTable(name="tb")
* @ORMEntity(repositoryClass = "AppBundleEntityTradetbRepository")
* @ORMHasLifecycleCallbacks()
* @package AppBundleEntityTrade
*/
class tb {
/**
* @ORMColumn(type="integer",unique=true)
* @AssertNotBlank(message="账号ID不能为空")
* @ORMId
*/
private $id;
/**
* @ORMColumn(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();
}
}

它不会以这种方式工作。Doctrine的EntityManager只支持单个数据库内实体的管理,因此tatb之间的跨数据库关系不会建立。有关更多信息,请参阅条令错误跟踪器中的此问题。

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

您需要在代码中创建一些更改:

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

namespace AppBundleEntity;
class ta
{
/**
* @ORMColumn(type="integer", nullable=true)
* @var int
*/
private $tb_table;  // Notice that it is not a reference anymore, but simple integer
/**
* Set tbTable.
*
* @param AppBundleEntityTradetb|null $tbTable
*
* @return ta
*/
public function setTbTable(AppBundleEntityTradetb $tbTable = null)
{
// You can also consider updating this method to accept plain integers aswel
$this->tb_table = $tbTable instanceof AppBundleEntityTradetb ? $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 AppBundleEntity;
use DoctrineORMEntityManager;
use DoctrineORMEntityRepository;
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 AppBundleEntityTradetb|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(AppBundleEntityTradetb::class, $tbId);
}
}

defaultController.php

namespace AppBundleController;
use DoctrineORMEntityManager;
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();
}
}
}

相关内容

  • 没有找到相关文章

最新更新