0

I've created a new service in my project. This service is configured in XML. I'd like to user the EntityManager, to retreive som data in the service but I'm not able to «connect» Doctrine to my service. Currently, I have this code:

services.xml

<service id="SiteService.search" class="Site\ProductBundle\Search\SphinxSearch" factory-service="doctrine.orm.entity_manager" factory-method="getRepository">
<argument>Site\ProductBundle\Entity\Product</argument>
</service>

SphinxSearch.php

namespace Dada\FilmsBundle\Search;
use Symfony\Component\DependencyInjection\ContainerAware;
class DadaSearch extends ContainerAware{
    //Some stuff
    public function fullNoPrivateByTitle($query){
        //Call $this->getResultsFromId($idlist);
    }
    private function getResultsFromId($idlist){
    $doctrine = $this->container->get('doctrine')->getManager()->getRepository('SiteProductBundle:Product');
    //Rest of the method
    }

With this code, I got a strange error. Seems like Symfony think my service is a sort of new Doctrine:

Undefined method 'fullNoPrivateByTitle'. The method name must start with either findBy or findOneBy! 500 Internal Server Error - BadMethodCallException

Can somebody help me with the configuration of my service? Thanks a lot.

chindit
  • 919
  • 2
  • 9
  • 19
  • Take a look at this [post](http://stackoverflow.com/questions/9172586/the-method-name-must-start-with-either-findby-or-findoneby-undefined-method-sym) it can hepe you – Maraboc May 20 '15 at 15:10
  • is this post helped you ?? – Maraboc May 20 '15 at 15:27

1 Answers1

3

Your implementation is confused in a few different ways.

  1. The object returned by a factory-method must be of the same type defined in the class attribute - so something that inherits from Doctrine\ORM\EntityRepository (this is where your "strange error" is coming from)
  2. It doesn't make sense to define a service but then make it extend ContainerAware. The whole point of defining services is to inject dependencies via configuration - not pluck them from the container at runtime.
  3. Inconsistent naming - your service references Site\ProductBundle\Search\SphinxSearch but your class is actually namespaced as Dada\FilmsBundle\Search\DataSearch

You have two options for injecting an EntityRepository: Use a factory as you're attempting-to here, or use the expression language

The factory approach should look like this (assuming the proper repository is ProductRepository

<service
    id="repository.product"
    class="Site\ProductBundle\Entity\ProductRepository"
    factory-service="doctrine.orm.entity_manager"
    factory-method="getRepository"
>
    <argument>Site\ProductBundle\Entity\Product</argument>
</service>

<service id="SiteService.search" class="Site\ProductBundle\Search\SphinxSearch">
   <argument type="service" id="repository.product"/>
</service>

The expression syntax would look like this

<service id="SiteService.search" class="Site\ProductBundle\Search\SphinxSearch">
   <argument type="expression">service('doctrine.orm.entity_manager').getRepository('ProductBundle:Product')</argument>
</service>

Then in your service class

<?php

namespace Site\ProductBundle\Search;

class SphinxSearch
{
    /**
     * @var \Site\ProductBundle\Entity\ProductRepository
     */
    protected $repository;

    public function __construct(ProductRepository $repository) {
        $this->repository = $repository;
    }

    private function getResultsFromId($idlist) {
        // Do whatever with $this->repository
    }
}
Peter Bailey
  • 105,256
  • 31
  • 182
  • 206