user1912241
user1912241

Reputation: 31

Doctrine2 "Class does not exist" error when calling an entity repository

I have some problems with the annotations system of doctrine 2 (I use the 2.3 that I integrated into Zend framework 2). On relatively simple relation I have no problems, but there I have many tables in cascade and when I call the repository find method, I get a Class does not exist error here :

doctrine\orm\lib\Doctrine\ORM\Proxy\ProxyFactory.php:233

There's probably some problems with the database schema itself, but I can't change it, I have to make my app from this database.

All my entities starts by :

namespace Gcl\Entities;
use Doctrine\ORM\Mapping as ORM;

Here's some of my entities :

TCompanyGcl

    /**
     * TCompanyGcl
     *
     * @ORM\Table(name="T_COMPANY_GCL")
     * @ORM\Entity(repositoryClass="Gcl\Repositories\TCompanyGclRepository")
     */
    class TCompanyGcl
    {
           /**
             * @var ArrayCollection $customerAccounts
             *
             * @ORM\OneToMany(targetEntity="TCustomerAccount", mappedBy="tCompanyGcl")
             */
            private $customerAccounts;

TCustomerAccount

/**
 * TCustomerAccount
 *
 * @ORM\Table(name="T_CUSTOMER_ACCOUNT")
 * @ORM\Entity
 */
class TCustomerAccount
{
   /**
     * @var \TCompanyGcl
     *
     * @ORM\ManyToOne(targetEntity="TCompanyGcl", cascade={"all"}, fetch="EAGER")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="COMPANY_ID", referencedColumnName="COMPANY_ID")
     * })
     */
    private $tCompanyGcl;

    /**
     * @var \TPerson
     *
     * @ORM\ManyToOne(targetEntity="TPerson", cascade={"all"}, fetch="EAGER")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="PERSON_ID", referencedColumnName="PERSON_ID")
     * })
     */
    private $person;

    /**
     * @var ArrayCollection $customerSubscriptions
     *
     * @ORM\OneToMany(targetEntity="TSubscription", mappedBy="customerAccount")
     */
    private $customerSubscriptions;

TSubscriptions

/**
 * TSubscription
 *
 * @ORM\Table(name="T_SUBSCRIPTION")
 * @ORM\Entity(repositoryClass="Gcl\Repositories\TSubscriptionRepository")
 */
class TSubscription
{
   /**
     * @var \TCustomerAccount
     *
     * @ORM\ManyToOne(targetEntity="TCustomerAccount", inversedBy="customerSubscriptions")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="CUSTOMER_ACCOUNT_ID", referencedColumnName="CUSTOMER_ACCOUNT_ID")
     * })
     */
    private $customerAccount;

So the problem is that when I do things like :

$account = $em->getRepository('Gcl\Entities\TCustomerAccount')->find(1);
$account->getSubscriptions();
$account->getCompanyGcl();

It works, or when I go all the way down to subscriptions from TCompanyGcl it also works. But when I do :

$subscription = $em->getRepository('Gcl\Entities\TSubscription')->find(1);

I get the error described above.

If somebody have the slightest lead on the problem I would greatly appreciate the help.

EDIT : Here's the repositories : TCompanyGclRepositories

namespace Gcl\Repositories;

use Doctrine\ORM\EntityRepository;

class TCompanyGclRepository extends EntityRepository
{
    /**
     * Récupère la liste des sociétés dont le champ passé en paramètre contient la chaîne de caractères passée en paramètre
     *
     * @param string field nom du champ dans lequel chercher
     * @param string search chaîne de recherche
     * @return Array company
     */
    public function getCompaniesByField($field = 'companyName', $search = '', $return_mode = 'array'){
        $qb = $this->_em->createQueryBuilder();
        $qb->select('c')
        ->from('Gcl\Entities\TCompanyGcl',  'c')
        ->where('UPPER(c.'.$field.') LIKE :search')
        ->setParameter('search', "%".mb_strtoupper($search,'UTF-8')."%");

        if($return_mode=="array"){
            $results = $qb->getQuery()->getArrayResult();
            $companies = array(0 => "Pas de société");

            foreach($results as $result){
                $companies[$result['companyId']] = $result;
            }
        }
        else{
            $companies = $qb->getQuery()->getResult();
        }

        return $companies;
    }

    public function getCustomerAccountPerson($companyId){
        $qb = $this->_em->createQueryBuilder();
        $qb->select('cust, p, t')
                    ->from('Gcl\Entities\TCustomerAccount', 'cust')
                    ->leftJoin('cust.person', 'p')
                    ->leftJoin('p.typeofcivility', 't')
                    ->where('cust.companyId = :id')
                    ->setParameter('id', $companyId);
        return $qb->getQuery()->getResult();

    }
}

TSubscriptionRepositories

namespace Gcl\Repositories;

use Doctrine\ORM\EntityRepository;

class TSubscriptionRepository extends EntityRepository
{
    public function getContractTickets($subscription_id){
        $qb = $this->_em->createQueryBuilder();

        if(!is_array($subscription_id)){
            $subscription_id = array($subscription_id);
        }
        $qb->select('s, t, i, s.itemId, s.subscriptionId, i.printName, t.ticketSerialNumber')
        ->from('Gcl\Entities\TSubscription', 's')
        ->innerJoin('s.ticketSerialNumber', 't')
        ->leftJoin('s.item', 'i')
        ->add('where', $qb->expr()->in('s.subscriptionId', $subscription_id));
        return $qb->getQuery()->getArrayResult();
    }

    public function getContractVehicles($subscription_id){
        $qb = $this->_em->createQueryBuilder();

        if(!is_array($subscription_id)){
            $subscription_id = array($subscription_id);
        }
        $qb->select('s, v, tv, s.itemId, i.printName, v.licencePlate, tv.name')
        ->from('Gcl\Entities\TSubscription', 's')
        ->innerJoin('s.licencePlate', 'v')
        ->leftJoin('v.typeOfVehicle', 'tv')
        ->leftJoin('s.item', 'i')
        ->add('where', $qb->expr()->in('s.subscriptionId', $subscription_id));
        return $qb->getQuery()->getArrayResult();
    }
}

My Entities are in the folder Gcl/Entities and my repositories in Gcl/Repositories. When I remove some associations from the entites I can call them and their methods just fine. But if when calling the find method on the Subscription repositories I remove the tCompanyGcl and person associations from TCustomerAccount I get this error :

Class Gcl\Entities\ArrayCollection does not exist

Upvotes: 1

Views: 5737

Answers (2)

user1912241
user1912241

Reputation: 31

I found the problem, can't believe it was so simple and right before my eyes. The fact that removing annotations was removing the error led me to think that the source was the annotations, but the problem was from the setter methods.

For example the getCompanyGcl method on TCustomer :

/**
 * Set companyGcl
 *
 * @param \TCompanyGcl $companyGcl
 * @return TCustomerAccount
 */
public function setCompanyGcl(\TCompanyGcl $companyGcl = null)
{
    $this->companyGcl = $companyGcl;

    return $this;
}

But to work you have to precise the namespace of the object in parameter, like this :

/**
 * Set companyGcl
 *
 * @param \TCompanyGcl $companyGcl
 * @return TCustomerAccount
 */
public function setCompanyGcl(\Gcl\Entities\TCompanyGcl $companyGcl = null)
{
    $this->companyGcl = $companyGcl;

    return $this;
}

Upvotes: 2

Lighthart
Lighthart

Reputation: 3666

Your TclCustomerAccount respository is not specified, which means you are using the default. That should work flawlessly. You don't mention whether or not you can use your custom repository from TCompanyGcl.

My guess is your paths to the custom repositories are wrong OR the class names of the repositories are misspelled (or differently spelled from your annotations) in the repository files themselves.

You'll have to post the repository files themselves if you want more help.

Edits:

I am weak on annotations, I don't use them. However, I think

@var ArrayCollection $customerSubscriptions 

is combining with

namespace Gcl\Repositories; 

to produce this error. Specify the entire ArrayCollection path in the annotation via:

use Doctrine\Common\Collection\ArrayCollection as ArrayCollection; 

at the head of the file or in every annotation individually as

@var Doctrine\Common\Collection\ArrayCollection $customerSubscriptions 

and similar

Upvotes: 1

Related Questions