主义多对一的关系坚持运作

时间:2013-03-23 11:58:15

标签: php mysql doctrine-orm

我有一个故事表和用户表。故事表中的列userid是一个外键,它引用用户表中的id。

我设置的关系是用户可能有很多故事存储在故事表中。我已经创建了两个表的实体。

但是如果尝试仅将操作持续到故事表,则会询问新用户输入的详细信息。

我的目标是添加一个现有userId的新故事。

我在这里发布错误:

  

通过“Story#_userId”关系找到了一个新实体   未配置为级联实体的持久操作:   用户@ 0000000038960c50000000008ea93852。解决这个问题:要么   显式调用此未知实体上的EntityManager#persist()或   例如,configure cascade在映射中保持此关联   @ManyToOne(..,级联= {\ “坚持\”})。

我在Story实体中设置了ManyToOne关系:

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

private $_userId;  

我检查了数据库架构,它显示了关系设置正确。所以我完成了故事插入过程。

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

5 个答案:

答案 0 :(得分:23)

你可能是故事实体而不是用户。如果您有这样的事情:

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

这将导致致命错误,因为您持久保存一个实体,但通过其关系,Doctrine会找到另一个新实体。您有两种选择:

呼叫在两个实体上持续存在:

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

或者,为Story实体设置级联持久性。例如。如果你使用注释映射,你会做类似的事情

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

章节8. Working with associations详细说明了这一点。

答案 1 :(得分:5)

ķ。诺伯特的回答很明显,但有些事情可能不清楚。至少我不清楚是谁,他从SQL中学到了教义。

事情是学说似乎记得哪些对象已经存在。每当它找到与您想要持久存在的实体相关的(非持久性)对象时,它会通过“通过关系找到新实体...”错误而大喊大叫。当您想要保存新对象(只有一个实体,而不保留相关实体)时,您只需要确保相关实体已经保留。 所以:

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

诀窍。因为doctrine知道用户已经存在并且不再需要这样做了。 Doctrine知道因为我们从数据库中获得了用户。

答案 2 :(得分:0)

我很难理解你的需求,所以我不确定这是否会回应你的问题。

由于story.user_id是user.id(它是主键)的外键,因此不能为空/ null。因此,假设您有一个php会话,您应该将您的用户ID(或用户名)存储在会话变量中,并且当您在故事表中创建新记录时,请使用会话中的用户ID来填充story.user_id属性。

希望它有所帮助。

答案 3 :(得分:0)

如果你附上你的演员,我会很有帮助。

但我认为这是我的同类问题。您无法在一个字段中一起定义@Id和@ManyToOne。您必须为@Id和关系@ManyToOne使用单独的字段。

如果你有一个新的(非持久的)用户实体,你必须坚持使用cascade = {“persist”}或cascade = {“all”}字段对应于Story实体的用户。只有当User已经存在并且它附加到Doctrine时,您才可以存储Story实体。

希望有所帮助。

答案 4 :(得分:0)

您认为不应为User设置Userid而不是story

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