In order to have a well separated structure on my project, I want to put Embeddable classes on the Embeddable namespace, not Entity:
namespace AppBundle\Embeddable;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Embeddable
*
* @author Sullivan Senechal <[email protected]>
*/
final class BillingRecipient
{
/**
* @var string
*
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $name;
/**
* @var string
*
* @ORM\Column(type="text", nullable=true)
*/
private $address;
/**
* @var string
*
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $company;
/**
* @var string
*
* @ORM\Column(type="string", length=32, nullable=true)
*/
private $siret;
/**
* @var string
*
* @ORM\Column(type="string", length=32, nullable=true)
*/
private $nif;
// Getters / Setters stuff...
}
And my mapping configuration, simple as hell:
doctrine:
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore
default_repository_class: AppBundle\Repository\DefaultRepository
mappings:
AppBundle: ~
But I got this error:
[Doctrine\Common\Persistence\Mapping\MappingException]
The class 'AppBundle\Embeddable\BillingRecipient' was not found in the chain configured namespaces AppBundle\Entity, Gedmo\Translatable\Entity, Gedmo\Translator\Entity, Gedmo\Loggable\Entity, Gedmo\Tree\Entity, FOS\OAuthServerBundle\Entity, FOS\UserBundle\Model
This can be easily fixed with this configuration workaround
doctrine:
orm:
auto_generate_proxy_classes: '%kernel.debug%'
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore
default_repository_class: AppBundle\Repository\DefaultRepository
mappings:
AppBundle: ~
# We need to define the Embeddable folder manually
# because doctrine only looks at the Entity folder for automatic configuration.
AppBundle_embeddable:
type: annotation
dir: '%kernel.root_dir%/../src/AppBundle/Embeddable'
prefix: AppBundle\Embeddable
is_bundle: false
But I think this make sense to consider the Embeddable directory for the automatic configuration, and get rid of this trick.
What do you think?
I don't like the idea of separation between Entity and Embeddable. This usually leads highly coupled and not cohesive modules.
Instead maybe we could add kind of MappingProvider interface which will be allowed to implement by your bundle, which will allow to specify multiple locations to search for entities and allow this kind of customizations:
class AppBundle implements DoctrineMappingProvider
{
public function getMappingObjectDefaultNames()
{
return [
'Entity',
'Embeddable',
'CustomModule'
];
}
}
Right now the only possible way for me, for example, to have two modules which contains entities within single bundle is global mapping configuration (or override DoctrineExtension).
But this should be done in Symfony's Doctrine Bridge.
I never was a convention about separating embeddables into a separate namespace. So I'm -1 on adding this folder as auto-detected folder.
Being able to have non-standard conventions is precisely the reason why we support explicit configuration.
Agree with @stof. Closing.
Most helpful comment
I never was a convention about separating embeddables into a separate namespace. So I'm -1 on adding this folder as auto-detected folder.
Being able to have non-standard conventions is precisely the reason why we support explicit configuration.