Doctrinebundle: Integrate Embeddable for bundle mapping automatic configuration

Created on 7 Dec 2016  路  3Comments  路  Source: doctrine/DoctrineBundle

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?

Won't Fix

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.

All 3 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

KartaviK picture KartaviK  路  4Comments

smurfy picture smurfy  路  7Comments

Sjeijoet picture Sjeijoet  路  4Comments

blackandred picture blackandred  路  7Comments

scourgen picture scourgen  路  8Comments