2012-10-28 5 views
2

J'ai une entité utilisateur. Ceci est considéré comme l'entité principale dans ce cas et le simple fait qu'il est utilisé signifie qu'il est présent.Une relation OneToOne facultative entre les entités?

L'entité Utilisateur a une entité Store. Mais tous les utilisateurs n'auront pas nécessairement une entité Store.

Il est à noter qu'il s'agit d'une base de données existante avec laquelle nous travaillons, et l'ID de la table User est le même que celui de la table Store. Nom (id) et valeur. C'est juste que dans certains cas, Store n'a pas d'enregistrement pour un identifiant d'utilisateur donné.

utilisateur:

class User extends Entity 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="string", length=36) 
    */ 
    protected $id; 

    /** 
    * @ORM\OneToOne(targetEntity="Store") 
    * @ORM\JoinColumn(name="id", referencedColumnName="id") 
    */ 
    protected $store; 

    ... 
} 

magasin:

class Store extends Entity 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="string", length=36) 
    */ 
    protected $id; 

    ... 
} 

Cela provoque des problèmes dans les contrôleurs. Si une entité utilisateur ne possède pas d'enregistrement Store, elle échoue avec une exception "Entité non trouvée". Cela peut être traité en utilisant un try try assez facile (je n'ai pas été capable de trouver un moyen de vérifier si un objet Entity existe ou est juste un proxy). Si l'utilisateur a avoir un enregistrement de magasin, tout va bien ici.

Mais la grande question que j'ai est particulièrement Fixtures:

protected function createUser($id) 
{ 
    $user = new User(); 
    $user->setId($id); 
    $user->setEmail($id.'@example.com'); 
    $user->setUserName($id.'_name'); 
    $user->setArea($this->manager->find('Area', 156)); // Global 

    $this->manager->persist($user); 

    return $user; 
} 

Quand je lance Fixtures, cette tentative échoue. Me donner l'erreur "Violation de la contrainte d'intégrité: 1048 Colonne 'id' ne peut pas être nul". Ce message disparaît si je supprime l'entité de magasin de l'utilisateur. Donc, en un mot, je ne peux pas ajouter un utilisateur s'il n'a pas de magasin.

Quelqu'un sait ce qui se passe? J'ai fait quelques recherches et je ne trouve rien, y compris les docs de doctrine, sur les relations optionnelles entre Entités. Ce que je pensais aurait été une situation commune.

Répondre

1

a trouvé la solution à ce sur cette page doc:

http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-3-join-table-with-metadata

Dans mon cas, plutôt que l'entité utilisateur étant associé à l'entité de magasin en utilisant le champ id, la propriété du magasin dans l'entité utilisateur serait associé à l'entité Store par utilisateur (un objet entité). En retour, l'objet Store contiendra une entité utilisateur, qui est annotée comme identifiant de l'entité.

Je suis sûr que c'est aussi déroutant que l'enfer, il suffit de regarder l'exemple ci-dessus. Voici mes classes ajustées Entité:

utilisateur

class User extends Entity 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="string", length=36) 
    */ 
    protected $id; 

    /** 
    * @ORM\OneToOne(targetEntity="Store", mappedBy="user") 
    */ 
    protected $store; 

    ... 
} 

Magasin

class Store extends Entity 
{ 
    /** 
    * @ORM\Column(type="string", length=36) 
    */ 
    protected $id; 

    /** 
    * @ORM\Id 
    * @ORM\OneToOne(targetEntity="User") 
    * @ORM\JoinColumn(name="id", referencedColumnName="id") 
    */ 
    protected $user; 

    ... 
} 

Maintenant, s'il n'y a pas présente record de magasin pour un utilisateur donné, la propriété du magasin dans l'entité utilisateur sera nul. Les montages fonctionnent comme prévu aussi.

0

En plus de la réponse ci-dessus, j'ai également besoin d'ajouter un attribut inversedBy. Sinon, une erreur de mappage d'entité non valide sera générée.

En utilisant les entités ci-dessus, l'objet Store devrait ressembler à ceci:

class Store extends Entity 
{ 
/** 
* @ORM\Column(type="string", length=36) 
*/ 
protected $id; 

/** 
* @ORM\Id 
* @ORM\OneToOne(targetEntity="User", inversedBy="store") 
* @ORM\JoinColumn(name="id", referencedColumnName="id") 
*/ 
protected $user; 

... 
} 
Questions connexes