web-dev-qa-db-fra.com

Doctrine plusieurs à un relation persistent opération

J'ai une table d'histoire et une table d'utilisateur. La colonne userid dans la table de story est une clé étrangère qui fait référence à l'id de la table user.

J'ai établi la relation est qu'un utilisateur peut avoir plusieurs histoires qui sont stockées dans la table des histoires. J'ai créé les entités des deux tables.

Mais si vous essayez de continuer l'opération uniquement dans la table de scénario, il demande les détails de la nouvelle entrée utilisateur.

Mon objectif est d’ajouter une nouvelle histoire avec la variable userId existante.

Je poste l'erreur ici:

Une nouvelle entité a été trouvée dans la relation 'Story # _userId' qui N'a pas été configurée pour mettre en cascade des opérations persistantes pour l'entité: Utilisateur @ 0000000038960c50000000008ea93852. Pour résoudre ce problème: appelez explicitement EntityManager # persist () sur cette entité inconnue ou appelez Configurer en cascade cette association dans le mappage, par exemple @ManyToOne (.., cascade = {\ "persist \"}).

J'ai défini la relation ManyToOne dans l'entité Story:

/**
 * @ManyToOne(targetEntity="User", inversedBy = "_story" )
 * @JoinColumns({
 *     @JoinColumn(name="user_id", referencedColumnName="id")
 * })
 */

private $_userId;  

J'ai vérifié le schéma de base de données et il montre que la relation est définie correctement. J'ai donc fait le processus d'insertion de l'histoire.

$user = new User();
$user->setUserId($id);
$story = new Story();
$story->setContent("....");
$story->setUserid($user);
$this->em->persist($story);
$this->em->flush();
14
Sujith

Vous persistez probablement dans l'entité de récit mais pas l'utilisateur. Si vous avez quelque chose comme ça:

$story = new Story();
$user = new User();
$story->setUser($user);
$em->persist($story);
$em->flush();

Cela entraînera une erreur fatale, puisque vous persistez dans une entité, mais à travers ses relations, Doctrine trouve une autre nouvelle entité. Vous avez deux options:

L'appel persiste sur les deux entités:

$story = new Story();
$user = new User();
$story->setUser($user);
$em->persist($story);
$em->persist($user);
$em->flush();

Ou, configurez la persistance en cascade pour l'entité Story. Par exemple. si vous utilisez un mappage d'annotation, vous feriez quelque chose comme 

/**
 * @ManyToOne(targetEntity="User", inversedBy="stories", cascade={"persist"})
 */
private $author;

Le chapitre 8. Travailler avec des associations détaille ceci.

23
K. Norbert

La réponse de K. Norbert frappe, mais il y a quelque chose qui pourrait ne pas être clair. Au moins, ce n'était pas clair pour moi, qui suis venu à la doctrine de SQL.

La chose est que la doctrine semble se rappeler quels objets ont déjà persisté. Chaque fois qu'il trouve nouveau (pas encore conservé) les objets liés à l'entité que vous voulez conserver - il crie avec l'erreur 'Une nouvelle entité a été trouvée par la relation ...'. Lorsque vous souhaitez enregistrer un nouvel objet (une seule entité, sans entités associées persistantes), vous devez simplement vous assurer que les entités associées sont déjà persistantes. Ainsi:

$story = new Story();
$entityManager->find('User', $id);
$story->setUser($user);
$em->persist($story);
$em->flush();

fait le tour. Parce que doctrine sait que l'utilisateur est déjà persistant et qu'il n'a plus besoin de le faire. Doctrine le sait parce que nous avons obtenu l'utilisateur de la base de données.

4
BartBiczBoży

J'ai du mal à comprendre ce dont vous avez besoin, alors je ne suis pas sûr que cela réponde à votre question.

En tant que story.user_id id, une clé étrangère de user.id (qui est une clé primaire), elle ne peut pas être vide/nulle. Donc, si, par exemple, vous avez une session php, vous devriez probablement stocker votre identifiant utilisateur (ou nom d'utilisateur) dans vos variables de session, et lorsque vous créez un nouvel enregistrement dans la table de récit, utilisez l'identifiant de l'utilisateur de votre session pour renseigner l'attribut story.user_id.

J'espère que ça aide.

0
ophintor

Ne pensez-vous pas que vous devriez définir User plutôt que Userid pour story

$user = new User();
$user->setUserId($id);
$story = new Story();
$story->setContent("....");
$story->setUser($user);   //change here
$this->em->persist($story);
$this->em->flush();
0
plain jane

Je serais utile si vous attachez vos entites.

Mais je suppose que c'est un problème similaire au mien. Vous ne pouvez pas définir @Id et @ManyToOne ensemble dans un seul champ. Vous devez utiliser des champs distincts pour un @ Id et pour la relation @ManyToOne.

Si vous avez une nouvelle entité utilisateur (non encore persistante), vous devez conserver l'utilisateur dont le champ cascade = {"persist"} ou cascade = {"all"} correspond au nom de l'entité Story. Vous pouvez stocker l'entité Story uniquement si l'utilisateur existe déjà et qu'il est associé à Doctrine.

J'espère que ça vous aidera.

0
Athlan