Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine many to one relationship persist operation

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();
like image 223
Sujith Avatar asked Mar 23 '13 11:03

Sujith


People also ask

How to extend DQL in Doctrine ORM?

Extending DQL in Doctrine ORM: Custom AST Walkers Generic count query for pagination Modify the Output Walker to generate Vendor specific SQL DQL User Defined Functions Registering your own DQL functions Date Diff Date Add Conclusion Implementing ArrayAccess for Domain Objects Option 1 Option 2 Read-only

Are objects missing when traversing associations in doctrine?

Although Doctrine allows for a complete separation of your domain model (Entity classes) there will never be a situation where objects are missing when traversing associations. You can walk all the associations inside your entity models as deep as you want.

Is a one to many Association bidirectional?

2 3 4 5 6 One-To-Many, Bidirectional A one-to-many association has to be bidirectional, unless you are using a join table. This is because the many side in a one-to-many association holds the foreign key, making it the owning side. Doctrine needs the many side defined in order to understand the association.

What is the many side of a one-to-many Association?

This is because the many side in a one-to-many association holds the foreign key, making it the owning side. Doctrine needs the many side defined in order to understand the association. This bidirectional mapping requires the mappedByattribute on the one side and the inversedByattribute on the many side.


3 Answers

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.

like image 60
K. Norbert Avatar answered Sep 20 '22 15:09

K. Norbert


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.

like image 6
BartBiczBoży Avatar answered Sep 18 '22 15:09

BartBiczBoży


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();
like image 1
plain jane Avatar answered Sep 17 '22 15:09

plain jane