php - 在特定实体对象的存储库中使用不同的实体管理器
问题描述
我已按照手册中的如何使用多个实体管理器和连接一章在我的应用程序中配置和使用不同的实体管理器,因为某些实体存储在不同的数据库服务器中。
在控制器中,我需要使用 2 个实体管理器:默认用于客户、号码和付款,另一个用于合同。
但是,当我为合同调用存储库自定义方法fetchMainByClient()
时,它应该使用“自定义”实体管理器而不是默认实体管理器,我收到一个数据库错误,这表明它正在使用存储库中的默认实体管理器。
执行 'SELECT ... FROM CONTRACTS c0_ WHERE c0_.ClientId = 时发生异常?AND c0_.Type = 'Main'' 带参数 [35736]:
SQLSTATE [42S02]:未找到基表或视图:1146 表 'DEFAULTDB.CONTRACTS' 不存在
如果我尝试使用已经可用的存储库方法,例如findOneBy()
.
我究竟做错了什么?
这是控制器、存储库的代码和合同实体标头,以及原则配置。这不是真实的,但它是相似的。
控制器
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 映射的实体标头
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 之类的位置并调整配置。
推荐阅读
- laravel-nova - 在 Nova 中是否可以使用带有条件数据字段的 BelongsToMany?
- javascript - 更改多个动态字段的 id
- java - 如何以最短的方式在 jshell 中定义一个空的字符串列表?
- azure - 通过 Intranet 向 Azure IoT 设备发送消息
- c# - 如何为每个查询创建一个“单元”测试以在测试资源管理器中显示结果
- python - 我想使用 rss 实现基于树的回归模型
- oracle - Oracle 表单注释行快捷方式
- karate - 空手道 - 没有并行赛跑者的概述报告
- javascript - 将滑块/滑动条设置为从第一张幻灯片自动播放
- c# - OR-Tools、CP-SAT 求解器 - 最大化然后最大化