Используйте другой Entity Manager в репозитории определенных объектов Entity - PullRequest
0 голосов
/ 01 июня 2018

Я следовал главе Как работать с несколькими менеджерами сущностей и соединениями в руководстве по настройке и использованию разных менеджеров сущностей в моем приложении, так как некоторые сущности хранятся на разных серверах баз данных.

В контроллере мне нужно использовать 2 менеджера сущностей: по умолчанию для клиентов, номеров и платежей, а другой для контрактов.

Однако, когда я вызываю пользовательский метод репозитория fetchMainByClient() дляВ контрактах, в которых вместо стандартного менеджера сущностей должен использоваться «пользовательский» менеджер, я получаю ошибку базы данных, которая показывает, что в хранилище используется менеджер сущностей по умолчанию.

Исключительная ситуация при выполнении 'ВЫБРАТЬ ... ИЗ КОНТРАКТОВ c0_ ГДЕ 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
{
    ...
}

1 Ответ

0 голосов
/ 04 июня 2018

Проблема заключается в том, что ваше соединение по умолчанию будет подбирать все сущности в App \ Entity, а также любые подкаталоги, такие как App \ Entity \ Custom.Таким образом, ваши пользовательские сущности отображаются на обоих менеджеров сущностей.

Конструктор хранилища сервисов просто просматривает каждого менеджера, чтобы увидеть, поддерживает ли он данную сущность.Первый найденный get - это хранилище.

Переместите App \ Entity \ Custom в нечто вроде App \ EntityCustom и настройте конфигурацию.

...