19
votes

I have a story table and user table. The column userid in story table is a foreign key which refers the id in user table.

I have set the relationship is that a user may have many stories which is stored in story table. I have created the entities of both table.

But if try to persist operation only to story table it is asking the details for new user entry.

My objective is to add a new story with existing userId.

Am posting the error here:

A new entity was found through the relationship 'Story#_userId' that was not configured to cascade persist operations for entity: User@0000000038960c50000000008ea93852. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={\"persist\"}).

I set ManyToOne relationship in Story entity:

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

private $_userId;  

I checked the database schema and it shows relationship is set correctly. So I have done the story insertion process.

$user = new User();
$user->setUserId($id);
$story = new Story();
$story->setContent("....");
$story->setUserid($user);
$this->em->persist($story);
$this->em->flush();
5
Is this problem occurring in an async process?sayil aguirre

5 Answers

29
votes

You are probably persisting the story entity but not the user. If you have something like this:

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

This will result in a fatal error, since you are persisting one entity, but through its relations, Doctrine finds another new entity. You have two options:

Call persist on both entities:

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

Or, set up cascading persist for the Story entity. Eg. if you are using annotation mapping, you would do something like

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

The chapter 8. Working with associations details this.

6
votes

K. Norbert's answer hits the spot, but there is something that might be unclear. At least it was unclear for me, who came to doctrine from SQL.

The thing is doctrine seem to remember which objects are already persisted. Whenever it finds new (not persisted yet) objects related to entity you want to persist - it yells with 'A new entity was found through the relationship ...' error. When you want to save new object (only one entity, without persisting related entities) you just need to make sure related entities are persisted already. So:

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

does the trick. Because doctrine knows the user is persisted already and it doesn't need to do it anymore. Doctrine knows because we got the user from the database.

1
votes

Dont you think you should set User rather than Userid for 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
votes

I'm struggling to understand what you need, so I'm not sure if this will respond to your question.

As the story.user_id id a foreign key of user.id (which is a primary key), this can't be empty/null. So if, let's say, you have a php session, you should probably store your user id (or user name) in your session variables, and when you create a new record in the story table, use the user id from your session to populate the story.user_id attribute.

Hope it helps.

0
votes

I would be helpful if you attach your entites.

But I suppose that it is simmilar problem to mine. You cannot define the @Id and @ManyToOne together in one field. You have to use separate fields for an @Id and for relation @ManyToOne.

If you have a new (not persisted yet) User entity, you have to persist User which have cascade={"persist"} or cascade={"all"} in field correspond to Story entity. You can store the Story entity only if User already exists and it is attached to Doctrine.

Hope it help.