使用自定义存储库时,动态EntityManager的find()方法返回“找不到表”

时间:2018-12-16 11:51:08

标签: symfony doctrine symfony4

首先,我将解释该解决方案的原因和工作方式,然后说明我遇到的问题。如果您认为有一种更好的方式来做我做的事,我很想听听。我也想知道为什么教义会以这种方式表现。

事实证明,我的应用程序需要根据客户端连接到其他数据库。我在固定数据库中有一个表,其中包含某些请求中使用的连接信息。 我已经成功完成了以下代码:

class DynamicEntityManager {

protected $em;
private $request;

private $client_id;

public function __construct(RequestStack $request, EntityManagerInterface $em){
    $this->em = $em;
    $this->request = $request;
}

public function getEntityManager(ClientConn $client = null) {
    $request = $this->request->getCurrentRequest();  
    if($client == NULL){
        $domain = $request->attributes->get('domain');
        if($domain == "" || $domain == NULL){
            throw new \Exception("Error de conexion", 1);
        }
        $client = $this->em->getRepository(ClientConn::class)->findOneBy(array(
            "subdomain" => $domain
        ));
        if($client == NULL){
            throw new \Exception("Error de conexion", 1);                
        }
    }
    $connectionDB = $client->getConnection();
    $dbdriver = 'oci8';
    $conexionSplit = explode(':',$connectionDB);
    $dbhost = $conexionSplit[0];
    $dbport = $conexionSplit[1];
    $dbname = $conexionSplit[2];
    $dbuser = $client->getUsuarioBd();
    $dbpass = $client->getClaveBd();
    $service = false;

    $this->client_id = $client->getId();

    if(strpos($dbname,'SN=') !== false){
        $parts = explode('=',$dbname);
        $dbname = $parts[1];
        $service = true;
    }

    $request->attributes->set('client_id',$client->getId());

    $conn = array(
        'driver'    => $dbdriver,
        'host'      => $dbhost,
        'port'      => $dbport,
        'dbname'    => $dbname,
        'user'      => $dbuser,
        'password'  => $dbpass,
        'service'   => $service,
        'charset'   => 'UTF8',
        'schema'    => null
    );
    return EntityManager::create($conn, $this->em->getConfiguration());
    }
}

您可以看到,我使用新连接返回了 EntityManager :: create($ conn,$ this-> em-> getConfiguration())。下一个是我的使用方式:

 /**
 * @Route("/api/client/{id}/conf/{confID}", name="conf.show")
 * @Method({"GET"})
 */
public function show(ClientConn $client, Request $request, DynamicEntityManager $dem ,$confId){
    try {

        $em = $dem->getEntityManager($client);
        $entity = $em->getRepository(Configuration::class)->find($confId);
        return new JsonResponse($entity, 200);
    }
    catch(\Exception $ex) {
        return new JsonResponse([
            "excepcion" => $ex->getMessage()
        ], $ex->getCode());
    }
}

它可以按预期运行,所以我相信,直到我看到该实体具有自定义存储库后,它便无法使用动态连接,因此,先前的路由将返回未找到表的异常。

  
      
  • @ORM \ Entity()<-像护身符一样
  •   
  • @ORM \ Entity(repositoryClass =“ App \ Repository \ ConfigurationRepository”)<-找不到表。
  •   

即使我不喜欢该解决方案,如果我再次创建连接,它也可以在存储库中使用。那么,我想要什么?我希望能够使用诸如find(),findBy()等基本方法,而不必每次使用自定义存储库时都重写它们。

class ConfigurationRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry, DynamicEntityManager $dem)
{
    parent::__construct($registry, Configuration::class);
    $this->dem= $dem;
}

public function uglyFind($client, $confID)
{        
    $query = $this->dem->getEntityManager($client)->createQueryBuilder('conf')
    ->select("conf")
    ->from(ConfPedidosLentes::class,'conf')
    ->where('conf.id = :value')->setParameter('value', $confID)
    ->getQuery();

    return $query->getOneOrNullResult();
}

我将非常感谢对此事的贡献和思想。

1 个答案:

答案 0 :(得分:0)

代替:

class ConfigurationRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry, DynamicEntityManager $dem)
    {
        parent::__construct($registry, Configuration::class);
        $this->dem= $dem;
    }
    ...

尝试扩展EntityRepository(不使用构造函数),并像在控制器中一样使用find:

use Doctrine\ORM\EntityRepository;

class ConfigurationRepository extends EntityRepository
{

}

ServiceEntityRepository是可选的EntityRepository基类,具有用于自动装配的简化构造函数,该基类将实体管理器显式设置为EntityRepository基类。由于您尚未将学说管理器配置为正确处理这些连接(实际上,使用如此多的连接甚至是不可能的),因此ServiceEntityRepository会将错误的EntityManager实例传递给EntityRepository子类,因此您不应该扩展ServiceEntityRepository但扩展EntityRepository