在特定实体的存储库中使用不同的实体管理器 objects
Use different Entity Manager in the Repository of specific Entity objects
我已按照手册中的 How to Work with multiple Entity Managers and Connections 章节在我的应用程序中配置和使用不同的实体管理器,因为一些实体存储在不同的数据库服务器中。
在控制器中,我需要使用 2 个实体管理器:默认用于客户、号码和付款,另一个用于合同。
但是,当我为合同调用存储库自定义方法 fetchMainByClient()
时,它应该使用 "custom" 实体管理器而不是默认的实体管理器,我收到一个数据库错误,这表明正在使用存储库中的默认实体管理器。
An exception occurred while executing 'SELECT ... FROM CONTRACTS c0_
WHERE c0_.ClientId = ? AND c0_.Type = 'Main'' with params [35736]:
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'DEFAULTDB.CONTRACTS' doesn't exist
如果我尝试使用已经可用的存储库方法,如 findOneBy()
。
,则会出现同样的错误
我做错了什么?
这是 Controller 的、Repository 的代码和 Contract 实体 header,以及 doctrine 配置。不是正品,但是很像。
控制器
public function index(Request $request, PaymentsRepository $payments_repository): Response
{
$payments = $payments_repository->findLatest($page, $this->getUser()->getId());
$form = $this->createForm(CreatePaymentType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$payment = $form->getData();
$em = $this->get('doctrine.orm.default_entity_manager');
$cr = $em->getRepository(Numbers::class);
$number = $tr->findOneByNumber($payment->getNumber());
if (!$number) {
$this->addFlash('error', 'numbers.missing_number');
} else {
$client = $number->getClients();
if (!$client) {
$this->addFlash('error', 'clients.missing_client');
} else {
//$em_custom = $this->get('doctrine.orm.custom_entity_manager');
$em_custom = $this->getDoctrine()->getManager('custom');
$contracts_repo = $em_custom->getRepository(Contracts::class);
//dump($em, $em_custom, $contracts_repo);
$contract = $contracts_repo->fetchMainByClient($client->getId());
$contracts_repo->increaseCredit($payment->getValue());
$payment->setDate(...);
$payment->setClientId($client->getId());
...
$em->persist($payment);
$em->flush();
$this->addFlash('success', 'flash.success_insert');
return $this->redirectToRoute('payments_paginated', ['page' => $page]);
}
}
}
return $this->render('carregamentos/index.html.twig', [
'payments' => $payments,
'form' => $form->createView(),
]);
}
存储库
namespace App\Repository;
use App\Entity\Custom\Contratos;
...
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
class ContractsRepository extends ServiceEntityRepository
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Contracts::class);
}
/**
* @return Contracts Returns the Contracts object for the ClientId
*/
public function fetchMainByClient($value): ?Contracts
{
return $this->createQueryBuilder('c')
->andWhere('c.clientid = :val')
->andWhere('c.type = \'Main\'')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
}
学说配置
doctrine:
dbal:
default_connection: default
connections:
default:
driver: 'pdo_mysql'
server_version: '5.6'
charset: utf8
default_table_options:
charset: utf8
collate: utf8_unicode_ci
url: '%env(resolve:DATABASE_URL)%'
custom:
driver: 'pdo_mysql'
server_version: '5.6'
charset: utf8
default_table_options:
charset: utf8
collate: utf8_unicode_ci
url: '%env(resolve:DATABASE_CUSTOM_URL)%'
mapping_types:
enum: string
set: string
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
Main:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: Main
custom:
connection: custom
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
Custom:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Custom'
prefix: 'App\Entity\Custom'
alias: Custom
具有 ORM 映射的实体 header
namespace App\Entity\Custom;
use Doctrine\ORM\Mapping as ORM;
/**
* Contracts.
*
* @ORM\Table(name="CONTRACTS", indexes={@ORM\Index(name="clientid", columns={"clientid"})})
* @ORM\Entity(repositoryClass="App\Repository\ContractsRepository")
*/
class Contracts
{
...
}
问题是您的默认连接将选取 App\Entity 中的所有实体以及任何子目录,例如 App\Entity\Custom。因此,您的自定义实体被映射到两个实体管理器。
服务存储库构造器只是查看每个管理器以查看它是否支持给定的实体。第一个找到的是存储库。
将 App\Entity\Custom 移动到类似 App\EntityCustom 的位置并调整配置。
我已按照手册中的 How to Work with multiple Entity Managers and Connections 章节在我的应用程序中配置和使用不同的实体管理器,因为一些实体存储在不同的数据库服务器中。
在控制器中,我需要使用 2 个实体管理器:默认用于客户、号码和付款,另一个用于合同。
但是,当我为合同调用存储库自定义方法 fetchMainByClient()
时,它应该使用 "custom" 实体管理器而不是默认的实体管理器,我收到一个数据库错误,这表明正在使用存储库中的默认实体管理器。
An exception occurred while executing 'SELECT ... FROM CONTRACTS c0_ WHERE c0_.ClientId = ? AND c0_.Type = 'Main'' with params [35736]:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'DEFAULTDB.CONTRACTS' doesn't exist
如果我尝试使用已经可用的存储库方法,如 findOneBy()
。
我做错了什么?
这是 Controller 的、Repository 的代码和 Contract 实体 header,以及 doctrine 配置。不是正品,但是很像。
控制器
public function index(Request $request, PaymentsRepository $payments_repository): Response
{
$payments = $payments_repository->findLatest($page, $this->getUser()->getId());
$form = $this->createForm(CreatePaymentType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$payment = $form->getData();
$em = $this->get('doctrine.orm.default_entity_manager');
$cr = $em->getRepository(Numbers::class);
$number = $tr->findOneByNumber($payment->getNumber());
if (!$number) {
$this->addFlash('error', 'numbers.missing_number');
} else {
$client = $number->getClients();
if (!$client) {
$this->addFlash('error', 'clients.missing_client');
} else {
//$em_custom = $this->get('doctrine.orm.custom_entity_manager');
$em_custom = $this->getDoctrine()->getManager('custom');
$contracts_repo = $em_custom->getRepository(Contracts::class);
//dump($em, $em_custom, $contracts_repo);
$contract = $contracts_repo->fetchMainByClient($client->getId());
$contracts_repo->increaseCredit($payment->getValue());
$payment->setDate(...);
$payment->setClientId($client->getId());
...
$em->persist($payment);
$em->flush();
$this->addFlash('success', 'flash.success_insert');
return $this->redirectToRoute('payments_paginated', ['page' => $page]);
}
}
}
return $this->render('carregamentos/index.html.twig', [
'payments' => $payments,
'form' => $form->createView(),
]);
}
存储库
namespace App\Repository;
use App\Entity\Custom\Contratos;
...
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
class ContractsRepository extends ServiceEntityRepository
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Contracts::class);
}
/**
* @return Contracts Returns the Contracts object for the ClientId
*/
public function fetchMainByClient($value): ?Contracts
{
return $this->createQueryBuilder('c')
->andWhere('c.clientid = :val')
->andWhere('c.type = \'Main\'')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
}
学说配置
doctrine:
dbal:
default_connection: default
connections:
default:
driver: 'pdo_mysql'
server_version: '5.6'
charset: utf8
default_table_options:
charset: utf8
collate: utf8_unicode_ci
url: '%env(resolve:DATABASE_URL)%'
custom:
driver: 'pdo_mysql'
server_version: '5.6'
charset: utf8
default_table_options:
charset: utf8
collate: utf8_unicode_ci
url: '%env(resolve:DATABASE_CUSTOM_URL)%'
mapping_types:
enum: string
set: string
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
Main:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: Main
custom:
connection: custom
naming_strategy: doctrine.orm.naming_strategy.underscore
mappings:
Custom:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Custom'
prefix: 'App\Entity\Custom'
alias: Custom
具有 ORM 映射的实体 header
namespace App\Entity\Custom;
use Doctrine\ORM\Mapping as ORM;
/**
* Contracts.
*
* @ORM\Table(name="CONTRACTS", indexes={@ORM\Index(name="clientid", columns={"clientid"})})
* @ORM\Entity(repositoryClass="App\Repository\ContractsRepository")
*/
class Contracts
{
...
}
问题是您的默认连接将选取 App\Entity 中的所有实体以及任何子目录,例如 App\Entity\Custom。因此,您的自定义实体被映射到两个实体管理器。
服务存储库构造器只是查看每个管理器以查看它是否支持给定的实体。第一个找到的是存储库。
将 App\Entity\Custom 移动到类似 App\EntityCustom 的位置并调整配置。