Fetching Related Objects exception when work with mutil database
when i use mutil database with doctrine to related objects ,it can't find the table in the right way.
ta is table name ,in the acc database.
tb is table name too,in the trade database.
ta record:
id name
1 ta名称
tb record:
id name
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' doesn't exist"
actully,tb is in the trade database.
how to fix these problem
<?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();
}
}
symfony doctrine-orm
add a comment |
when i use mutil database with doctrine to related objects ,it can't find the table in the right way.
ta is table name ,in the acc database.
tb is table name too,in the trade database.
ta record:
id name
1 ta名称
tb record:
id name
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' doesn't exist"
actully,tb is in the trade database.
how to fix these problem
<?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();
}
}
symfony doctrine-orm
add a comment |
when i use mutil database with doctrine to related objects ,it can't find the table in the right way.
ta is table name ,in the acc database.
tb is table name too,in the trade database.
ta record:
id name
1 ta名称
tb record:
id name
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' doesn't exist"
actully,tb is in the trade database.
how to fix these problem
<?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();
}
}
symfony doctrine-orm
when i use mutil database with doctrine to related objects ,it can't find the table in the right way.
ta is table name ,in the acc database.
tb is table name too,in the trade database.
ta record:
id name
1 ta名称
tb record:
id name
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' doesn't exist"
actully,tb is in the trade database.
how to fix these problem
<?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();
}
}
symfony doctrine-orm
symfony doctrine-orm
asked Jan 1 at 12:50


Neko ZhangNeko Zhang
104
104
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
It will not work in this way. Doctrine's EntityManager
only support management of entities within single database, so your cross-database relation between ta
and tb
will not be established. Please refer this issue in Doctrine bug tracker for more information.
However your goal can be accomplished into slightly different way. You can't establish cross-database relations between entities, but you can, of course, store ids that refers entities into different databases. Hence you can move all cross-database relations logic into repositories. For example let's assume that you have 2 EntityManager
for each database: $accEm
for acc
database and $tradeEm
for trade
database. Taking in mind that you're using Symfony - they can be configured into DoctrineBundle
configuration and then injected into services.
You will need to create some changes into your code:
ta.php, I've omitted most of code to express changes that needs to be made.
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, I've also omitted most of code that can be there
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();
}
}
}
Thank you very much!<br/> your solution is greate ,can you find out another way to fix it?<br/>
– Neko Zhang
Jan 2 at 14:30
@NekoZhang it is possible to avoid repository-based solution by add listener to PostLoad event and modify entity, but it may became quite complicated over time
– Flying
Jan 2 at 14:58
you are right,thank you again,i try read the doctrine doc again to find whether another way to fix it .thank you !
– Neko Zhang
Jan 2 at 16:32
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995582%2ffetching-related-objects-exception-when-work-with-mutil-database%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It will not work in this way. Doctrine's EntityManager
only support management of entities within single database, so your cross-database relation between ta
and tb
will not be established. Please refer this issue in Doctrine bug tracker for more information.
However your goal can be accomplished into slightly different way. You can't establish cross-database relations between entities, but you can, of course, store ids that refers entities into different databases. Hence you can move all cross-database relations logic into repositories. For example let's assume that you have 2 EntityManager
for each database: $accEm
for acc
database and $tradeEm
for trade
database. Taking in mind that you're using Symfony - they can be configured into DoctrineBundle
configuration and then injected into services.
You will need to create some changes into your code:
ta.php, I've omitted most of code to express changes that needs to be made.
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, I've also omitted most of code that can be there
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();
}
}
}
Thank you very much!<br/> your solution is greate ,can you find out another way to fix it?<br/>
– Neko Zhang
Jan 2 at 14:30
@NekoZhang it is possible to avoid repository-based solution by add listener to PostLoad event and modify entity, but it may became quite complicated over time
– Flying
Jan 2 at 14:58
you are right,thank you again,i try read the doctrine doc again to find whether another way to fix it .thank you !
– Neko Zhang
Jan 2 at 16:32
add a comment |
It will not work in this way. Doctrine's EntityManager
only support management of entities within single database, so your cross-database relation between ta
and tb
will not be established. Please refer this issue in Doctrine bug tracker for more information.
However your goal can be accomplished into slightly different way. You can't establish cross-database relations between entities, but you can, of course, store ids that refers entities into different databases. Hence you can move all cross-database relations logic into repositories. For example let's assume that you have 2 EntityManager
for each database: $accEm
for acc
database and $tradeEm
for trade
database. Taking in mind that you're using Symfony - they can be configured into DoctrineBundle
configuration and then injected into services.
You will need to create some changes into your code:
ta.php, I've omitted most of code to express changes that needs to be made.
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, I've also omitted most of code that can be there
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();
}
}
}
Thank you very much!<br/> your solution is greate ,can you find out another way to fix it?<br/>
– Neko Zhang
Jan 2 at 14:30
@NekoZhang it is possible to avoid repository-based solution by add listener to PostLoad event and modify entity, but it may became quite complicated over time
– Flying
Jan 2 at 14:58
you are right,thank you again,i try read the doctrine doc again to find whether another way to fix it .thank you !
– Neko Zhang
Jan 2 at 16:32
add a comment |
It will not work in this way. Doctrine's EntityManager
only support management of entities within single database, so your cross-database relation between ta
and tb
will not be established. Please refer this issue in Doctrine bug tracker for more information.
However your goal can be accomplished into slightly different way. You can't establish cross-database relations between entities, but you can, of course, store ids that refers entities into different databases. Hence you can move all cross-database relations logic into repositories. For example let's assume that you have 2 EntityManager
for each database: $accEm
for acc
database and $tradeEm
for trade
database. Taking in mind that you're using Symfony - they can be configured into DoctrineBundle
configuration and then injected into services.
You will need to create some changes into your code:
ta.php, I've omitted most of code to express changes that needs to be made.
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, I've also omitted most of code that can be there
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();
}
}
}
It will not work in this way. Doctrine's EntityManager
only support management of entities within single database, so your cross-database relation between ta
and tb
will not be established. Please refer this issue in Doctrine bug tracker for more information.
However your goal can be accomplished into slightly different way. You can't establish cross-database relations between entities, but you can, of course, store ids that refers entities into different databases. Hence you can move all cross-database relations logic into repositories. For example let's assume that you have 2 EntityManager
for each database: $accEm
for acc
database and $tradeEm
for trade
database. Taking in mind that you're using Symfony - they can be configured into DoctrineBundle
configuration and then injected into services.
You will need to create some changes into your code:
ta.php, I've omitted most of code to express changes that needs to be made.
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, I've also omitted most of code that can be there
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();
}
}
}
answered Jan 2 at 11:00
FlyingFlying
3,3391819
3,3391819
Thank you very much!<br/> your solution is greate ,can you find out another way to fix it?<br/>
– Neko Zhang
Jan 2 at 14:30
@NekoZhang it is possible to avoid repository-based solution by add listener to PostLoad event and modify entity, but it may became quite complicated over time
– Flying
Jan 2 at 14:58
you are right,thank you again,i try read the doctrine doc again to find whether another way to fix it .thank you !
– Neko Zhang
Jan 2 at 16:32
add a comment |
Thank you very much!<br/> your solution is greate ,can you find out another way to fix it?<br/>
– Neko Zhang
Jan 2 at 14:30
@NekoZhang it is possible to avoid repository-based solution by add listener to PostLoad event and modify entity, but it may became quite complicated over time
– Flying
Jan 2 at 14:58
you are right,thank you again,i try read the doctrine doc again to find whether another way to fix it .thank you !
– Neko Zhang
Jan 2 at 16:32
Thank you very much!<br/> your solution is greate ,can you find out another way to fix it?<br/>
– Neko Zhang
Jan 2 at 14:30
Thank you very much!<br/> your solution is greate ,can you find out another way to fix it?<br/>
– Neko Zhang
Jan 2 at 14:30
@NekoZhang it is possible to avoid repository-based solution by add listener to PostLoad event and modify entity, but it may became quite complicated over time
– Flying
Jan 2 at 14:58
@NekoZhang it is possible to avoid repository-based solution by add listener to PostLoad event and modify entity, but it may became quite complicated over time
– Flying
Jan 2 at 14:58
you are right,thank you again,i try read the doctrine doc again to find whether another way to fix it .thank you !
– Neko Zhang
Jan 2 at 16:32
you are right,thank you again,i try read the doctrine doc again to find whether another way to fix it .thank you !
– Neko Zhang
Jan 2 at 16:32
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53995582%2ffetching-related-objects-exception-when-work-with-mutil-database%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown