Reputation: 7243
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
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