在特定实体对象的存储库中使用不同的实体管理器 [英] Use different Entity Manager in the Repository of specific Entity objects

查看:35
本文介绍了在特定实体对象的存储库中使用不同的实体管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了如何使用多个实体管理器和连接 在我的应用程序中配置和使用不同的实体管理器的手册中的章节,因为一些实体存储在不同的数据库服务器中.

I've followed the How to Work with multiple Entity Managers and Connections chapter in the manual to configure and use different entity managers in my app, as some entities are stored in different database servers.

在控制器中,我需要使用 2 个实体管理器:默认用于客户、数字和付款,另一个用于合同.

In the controller I need to use the 2 entity managers: the default for clients, numbers and payments, and the other for contracts.

但是,当我为合同调用存储库自定义方法 fetchMainByClient() 时,应该使用自定义"实体管理器而不是默认的实体管理器,我收到一个数据库错误,这表明正在使用存储库中的默认实体管理器.

However, when I call the repository custom method fetchMainByClient() for contracts, which should use the "custom" entity manager instead of the default one, I get a database error, which shows that's using the default entity manager in the repository.

执行 'SELECT ... FROM CONTRACTS c0_ 时发生异常哪里 c0_.ClientId = ?AND c0_.Type = 'Main'' 带参数 [35736]:

An exception occurred while executing 'SELECT ... FROM CONTRACTS c0_ WHERE c0_.ClientId = ? AND c0_.Type = 'Main'' with params [35736]:

SQLSTATE[42S02]:未找到基表或视图:1146 表'DEFAULTDB.CONTRACTS' 不存在

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'DEFAULTDB.CONTRACTS' doesn't exist

如果我尝试使用已经可用的存储库方法,例如 findOneBy(),则会发生同样的错误.

The same error occurs if I try to use an already available repository method, like findOneBy().

我做错了什么?

这里是 Controller 的、Repository 的代码和 Contract 实体头,以及学说配置.这不是真的,但很相似.

Here's the Controller's, the Repository's code and the Contract entity header, as well as the doctrine configuration. It's not the real one, but it's similar.

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.因此,您的自定义实体被映射到两个实体管理器.

The problem is that your default connection will pick up all entities in App\Entity as well as any sub-directories such as App\Entity\Custom. So your custom entities are being mapped to both entity managers.

服务存储库构造函数只是查看每个管理器,看看它是否支持给定的实体.第一个找到 get 的存储库.

The service repository constructor just looks through each manager to see if it supports a given entity. First one found get's the repository.

将 App\Entity\Custom 移动到类似 App\EntityCustom 的地方并调整配置.

Move App\Entity\Custom to something like App\EntityCustom and adjust the config.

这篇关于在特定实体对象的存储库中使用不同的实体管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆