web-dev-qa-db-fra.com

Utilisation d'EntityManager dans les entités Doctrine 2.0

J'ai 2 entités: Country (id, name) et Mapping (id, object, internalId, externalId). Le pays et le mappage ne sont pas liés aux associations (car le mappage n'a pas seulement des lignes pour le pays). J'ai besoin d'obtenir un identifiant 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;
}

Des questions:

  1. Est-il recommandé d'utiliser EntityManager dans des entités? Si non, veuillez expliquer comment obtenir un identifiant externe dans mon cas?
  2. Peut-être est-il possible d'associer Country et Mapping à l'aide de fichiers yaml?

Merci d'avance!

33
Torchello

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

Vous devriez probablement vous fier aux objets de service pour gérer les opérations qui reposent sur le gestionnaire d'entités.

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

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

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

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}  
51
Bryan M.

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

La classe UnitOfWork dans doctrine hydratera toute entité qui implémente ObjectManagerAware avec le gestionnaire d'entités 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 d'implémenter 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 le gestionnaire d'entités manuellement, par exemple avec une méthode de définition.

12
juanmf

Je pense que vous devez utiliser des référentiels d'entités. Celles-ci sont détaillées dans la documentation, même si elles sont un peu difficiles à trouver. Voici un lien vers l'article Getting Started qui documente comment on créerait un "référentiel" de fonctions "d'accès" pour vos entités.

De plus, voici un pseudo-code pour vous aider à démarrer:

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {
9
MikeMurko

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

Ici sont quelques exemples d'utilisation des traits php 5.4 dans Doctrine2; dont l'une est appelée entité active et fournit une fonctionnalité de style d'enregistrement actif dans Doctrine 2, y compris l'accès au gestionnaire d'entités à partir de l'entité.

1
Fost