34 votes

Utilisation d'EntityManager dans les entités de Doctrine 2.0

J'ai 2 entités : Pays (id, nom) et Mapping (id, objet, internalId, externalId). Le Pays et le Mapping ne sont pas connectés par des associations (parce que le Mapping a des lignes pas seulement pour le pays). J'ai besoin d'obtenir l'id externe pour le pays en utilisant les conditions suivantes :

  • country.id = mapping.internalId
  • mapping.object = 'country'

Je prévois donc d'ajouter la fonction getExternalId() dans Country

function getExternalId() {
    $em = Registry::getEntityManager();

    $mapping = $em->getRepository('Mapping')->findOneBy(array(
        'object'     => 'country',
        'internalId' => $this->getId()
    ));

    return !empty($mapping) ? $mapping->getExternalId() : false;
}

Questions :

  1. Est-ce une bonne pratique d'utiliser EntityManager à l'intérieur des entités ? Si non, veuillez expliquer comment obtenir un identifiant externe dans mon cas ?
  2. Peut-être est-il possible d'associer Pays et Cartographie en utilisant des fichiers yaml ?

Merci d'avance !

52voto

Bryan M. Points 9403

Ce n'est pas une bonne idée de permettre à un objet entité de dépendre du gestionnaire d'entités. Cela lie l'entité à la couche de persistance, ce qui était un problème que Doctrine 2 essayait spécifiquement de résoudre. Le plus gros inconvénient de s'appuyer sur le gestionnaire d'entités est que cela rend votre modèle difficile à tester en isolation, loin de la base de données.

Vous devriez probablement vous appuyer sur des objets de service pour gérer les opérations qui dépendent du gestionnaire d'entités.

// CountryService
public function getExternalId($country) {}

En outre, vous pouvez créer des méthodes proxy sur votre modèle pour faire appel à un objet de service défini en externe. Un objet de service serait beaucoup plus facile à simuler lors des tests que le gestionnaire d'entités.

$country->setService($countryService);
$country->getExternalId();

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}

6 votes

Je suis à la recherche de bons tutoriels sur la mise en œuvre de services pour la doctrine. Quelqu'un connaît-il de bons tutoriels ?

0 votes

Dans ce cas, l'objet service doit-il être interne à l'entité ou peut-il être utilisé en dehors de celle-ci ? $service = new Country \ServiceObject ; $ExtId = $service->getExternalId($country) ;

0 votes

Mise en œuvre du service pour la doctrine : symfony.com/doc/current/book/service_container.html

13voto

juanmf Points 354

Ce n'est peut-être pas la meilleure idée, mais il existe un moyen simple de le faire.

El UnitOfWork dans la doctrine hydratera toute entité qui implémente ObjectManagerAware avec le gestionnaire d'entité et les métadonnées de classe pour cette entité.

Tout ce que vous avez à faire pour obtenir le gestionnaire d'entité dans votre entité est de mettre en œuvre l'interface comme indiqué dans l'exemple ci-dessous :

use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectManagerAware;

/**
 * @ORM\Entity
 */
class MyEntity implements ObjectManagerAware
{
    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
    {
        $this->em = $objectManager;
    }
}

Si vous créez une nouvelle entité plutôt que de l'interroger à partir de la base de données, vous devrez définir manuellement le gestionnaire d'entités, par exemple avec une méthode setter.

10voto

MikeMurko Points 1144

Je pense que ce que vous devez utiliser, ce sont les Entity Repositories. Ils sont détaillés dans la documentation, bien qu'il soit un peu difficile de trouver des informations à leur sujet. Voici un lien vers le Pour commencer qui explique comment créer un "référentiel" de fonctions d'accès pour vos entités.

En outre, voici un pseudo-code pour vous aider à démarrer :

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {

0 votes

On dirait que le lien est mort

1 votes

En ce moment, le lien fonctionne. Je pense que c'est une très bonne solution à la question de l'OP.

4voto

Cobby Points 2396

Je pense que vous ne devriez JAMAIS utiliser l'EntityManager dans vos entités, comme @Byran M. l'a suggéré, utilisez une classe de service.

1voto

Fost Points 36

Un complément légèrement avant-gardiste (PHP 5.4 étant en alpha 2 au moment de cet article) qui pourrait être utile à l'avenir :

Aquí Voici quelques exemples d'utilisation des traits de php 5.4 dans Doctrine2 ; l'un d'entre eux s'appelle active entity et fournit une fonctionnalité de type enregistrement actif dans Doctrine 2, y compris l'accès au gestionnaire d'entités depuis l'entité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X