19

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

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

但是,如果尝试仅将操作持久化到故事表,则它会询问新用户条目的详细信息。

我的目标是在现有的userId.

我在这里发布错误:

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

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

/**
 * @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();
4

5 回答 5

30

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

$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 章使用关联对此进行了详细说明。

于 2013-03-24T00:34:32.097 回答
6

K. Norbert 的回答恰到好处,但有些事情可能不清楚。至少对于从 SQL 开始学说的我来说还不清楚。

问题是教义似乎记住了哪些对象已经被持久化。每当它找到与您想要持久化的实体相关的新(尚未持久化)对象时 - 它就会大喊“通过关系找到新实体......”错误。当您想保存新对象(只有一个实体,没有持久化相关实体)时,您只需要确保相关实体已经持久化。所以:

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

成功了。因为教义知道用户已经被持久化并且不需要再这样做了。Doctrine 知道是因为我们从数据库中获取了用户。

于 2015-03-07T06:56:53.667 回答
1

你不认为你应该设置而User不是Useridstory

$user = new User();
$user->setUserId($id);
$story = new Story();
$story->setContent("....");
$story->setUser($user);   //change here
$this->em->persist($story);
$this->em->flush();
于 2013-10-16T09:54:20.217 回答
0

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

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

希望能帮助到你。

于 2013-03-23T12:09:22.727 回答
0

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

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

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

希望它有所帮助。

于 2013-03-23T17:43:38.950 回答