noobie-php
noobie-php

Reputation: 7243

Target Entity Cannot be Found using ZF2

I am in a situation where i have created sort of 2 sub modules, what i was trying to achieve was mapping them using doctrine E.g i have a structure as follow:

I have 2 modules named 1)Account 2)Company

under Company I have 2 sub Modules named a)Company b)Currency, Similarly both have Separate controllers and entities. I have an Entity named as Voucher under Company. Now where problem comes When I try to map Account with Sub module named Company's Entity Currency i get this error.

 [Doctrine\ORM\Mapping\MappingException]                                      
The target-entity Currency\Entity\Currency cannot be found in 'Account\Enti  
 ty\Voucher#currency'.    

Here are my Entity Classes

  **Voucher Entity**

<?php

namespace Account\Entity;

use Doctrine\ORM\Mapping as ORM;
use Zend\Form\Annotation;

/**
 * A Main Voucher entity.
 *
 * @ORM\Entity
 * @ORM\Table(name="vouchers")
 * 
 * @property int $id
 * @property date $voucher_date
 * @property int $voucher_number
 * 
 * @Annotation\Name("Voucher")
 */
 class Voucher {

 /**
 * @ORM\Id
 * @ORM\Column(type="integer");
 * @ORM\GeneratedValue(strategy="AUTO")
 * 
 * @Annotation\Required(false)
 */
protected $id;

/**
 * @ORM\Column(type="integer")
 * 
 * @Annotation\Required(false)
 */
protected $voucher_number;

/**
 * @ORM\ManyToOne(targetEntity="VoucherType", inversedBy="vouchers")
 */
protected $voucher_type;

/**
 * @ORM\ManyToOne(targetEntity="Currency\Entity\Currency", inversedBy="vouchers")
 */
protected $currency;

/*
 * Constructor
 */

public function __construct() {
    $now = new \DateTime("now");
}

/**
 * Magic getter to retrieve protected properties.
 *
 * @param string $property     
 */
public function __get($property) {
    if ($property == 'name') {
        return $this->name();
    } else {
        return $this->$property;
    }
}

/**
 * Magic setter to save protected properties.
 *
 * @param string $property
 * @param mixed $value
 */
public function __set($property, $value) {
    $this->$property = $value;
}

public function getArrayCopy() {

}

public function exchangeArray($data) {
    $this->id = (isset($data['id'])) ? $data['id'] : null;
    $this->voucher_date = (isset($data['voucher_date'])) ? $data['voucher_date'] : null;
    $this->voucher_number = (isset($data['voucher_number'])) ? $data['voucher_number'] : null;
}



public function populate($data) {
    $this->id = isset($data['id']) ? $data['id'] : $this->id;
     $this->voucher_date = isset($data['voucher_date']) ? $data['voucher_date'] :   $this->category_name;
    $this->voucher_number = isset($data['voucher_number']) ? $data['voucher_number'] : $this->voucher_number;
}

}

Here is the Currency entity that is under Company module

 <?php

 namespace Company\Currency\Entity;

use Doctrine\ORM\Mapping as ORM;
use Zend\Form\Annotation;

/**
* A Main Voucher entity.
*
* @ORM\Entity
* @ORM\Table(name="currencies")
* 
* @property int $id
* @property string $name
* @property string $code
* 
* @Annotation\Name("Currency")
*/
 class Currency {

/**
 * @ORM\id
 * @ORM\GeneratedValue(strategy="AUTO")
 * @ORM\Column(type="integer")
 */
protected $id;

/** @ORM\Column(type="string") 
 */
protected $name;

/** @ORM\Column(type="string") 
 */
protected $code;

/**
 * @ORM\OneToMany(targetEntity="Account\Entity\Voucher", mappedBy="currency",  orphanRemoval=true)
 * 
 * @Annotation\Required(false)
 */
protected $vouchers;

/**
 * Magic getter to retrieve protected properties.
 *
 * @param string $property     
 */
public function __get($property) {
    if ($property == 'name') {
        return $this->name();
    } else {
        return $this->$property;
    }
}

/**
 * Magic setter to save protected properties.
 *
 * @param string $property
 * @param mixed $value
 */
public function __set($property, $value) {
    $this->$property = $value;
}

public function getArrayCopy() {

}

public function exchangeArray($data) {
    $this->id = (isset($data['id'])) ? $data['id'] : null;
    $this->name = (isset($data['name'])) ? $data['name'] : null;
    $this->code = (isset($data['code'])) ? $data['code'] : null;
}


public function populate($data) {
    $this->id = isset($data['id']) ? $data['id'] : $this->id;
    $this->name = isset($data['name']) ? $data['name'] : $this->name;
    $this->code = isset($data['code']) ? $data['code'] : $this->code;
}

}

Module.Config.php

<?php
namespace Company;

 return array(
'controllers' => array(
    'invokables' => array(
        'Company\Controller\Company' => 'Company\Controller\CompanyController',
    ),
 ),
 'router' => array(
    'routes' => array(
        'company' => array(
            'type' => 'segment',
            'options' => array(
                'route' => '/company[/][:action][/:id]',
                'constraints' => array(
                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'id' => '[0-9]+',
                ),
                'defaults' => array(
                    'controller' => 'Company\Controller\Company',
                    'action' => 'index',
                ),
            ),
        ),
    ),
 ),
// --------- Doctrine Settings For the Module
'doctrine' => array(
    'driver' => array(
        __NAMESPACE__ . '_driver' => array(
            'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
            'cache' => 'array',
            'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity')
        ),
        'orm_default' => array(
            'drivers' => array(
                __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
            )
        )
    )
),

'view_manager' => array(
    'template_path_stack' => array(
        'company' => __DIR__ . '/../view',
    ),
),
);

Correct me if i am wrong. From what I got the problem is that when I have 2 sub modules under 1 parent module like in my case. I get this problem, if I somewhat merge both sub modules under 1 Folder I think I will not get this error.

Upvotes: 1

Views: 832

Answers (1)

Jurian Sluiman
Jurian Sluiman

Reputation: 13558

The class name together with the namespace (so the FQCN, or Fully Qualified Class Name) is Company\Currency\Entity\Currency. You link from the voucher to the currency by Currency\Entity\Currency. So you are missing here the first Company part of the namespace.

Link to the proper FQCN and it will be fixed.

--

Update based on the config you posted:

You have an entity called Company\Currency\Entity\Currency. In your configuration you specify that you have entities in src/Company/Entity which holds the namespace Company\Entity. Therefore, the currency entity in your "submodule" is never found, Doctrine is not aware of it and therefore cannot map it to your voucher.

Pro tip: remove the submodules and make them a single module or use two normal modules. If you're quite new to the ZF2 module ecosystem, it can be tough to understand these cases. Having two "normal" modules would simplify this much more.

Upvotes: 3

Related Questions