学说多对一关系坚持操作


Doctrine many to one relationship persist operation

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

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

但是如果尝试只对story表进行持久化操作,则会询问新用户条目的详细信息。

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

我把错误贴在这里:

通过关系'Story#_userId'找到了一个新的实体未配置为为实体级联持久化操作:User@0000000038960c50000000008ea93852。要解决这个问题:要么在这个未知实体上显式地调用EntityManager#persist()例如,配置级联在映射中持久化此关联@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();

您可能在持久化故事实体,而不是用户。如果你有这样的内容:

$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章。使用关联详细说明了这一点。

诺伯特的回答很中肯,但有些地方可能不太清楚。至少对我来说是不清楚的,我是从SQL学来的。

问题是原则似乎记得哪些对象已经被持久化了。每当它发现新的(尚未持久化)对象与你想持久化的实体相关时,它就会大喊"通过关系找到了一个新的实体……"的错误。当您想保存新对象(只有一个实体,不持久化相关实体)时,您只需要确保相关实体已经持久化。所以:
$story = new Story();
$entityManager->find('User', $id);
$story->setUser($user);
$em->persist($story);
$em->flush();

就可以了。因为教条主义知道用户已经被持久化了它不需要再这样做了。Doctrine知道,因为我们从数据库中获取了用户

你不认为应该将story设置为User而不是Userid

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

我很难理解你需要什么,所以我不确定这是否会回答你的问题。

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

希望能有所帮助。

如果你附上你的实体,我会很有帮助的。

但我想这和我的问题是相似的。您不能在一个字段中同时定义@Id和@ManyToOne。@Id和@ManyToOne关系必须使用单独的字段。

如果你有一个新的(尚未持久化)用户实体,你必须持久化具有cascade={"persist"}或cascade={"all"}字段对应于Story实体的User。只有当User已经存在并且附加到Doctrine时,您才能存储Story实体。

希望有帮助。