学说多对一关系持续经营

2022-08-30 20:56:53

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

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

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

我的目标是用现有的.userId

我在这里发布错误:

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

我在实体中设置了多对一关系: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();

答案 1

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

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

這將導致一個致命的錯誤,因為你堅持一個實體,但通過它的關係,教義找到了另一個新的實體。您有两种选择:

在两个实体上调用持久化:

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

或者,为故事实体设置级联持久性。例如。如果您使用的是注释映射,则可以执行如下操作:

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

8章。使用关联会会详细说明了这一点。


答案 2

K.诺伯特的回答恰到好处,但有些事情可能不清楚。至少对我来说还不清楚,谁从SQL中得出了学说。

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

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

做伎俩。因为教义知道用户已经持久化了,它不再需要这样做了。教义知道,因为我们从数据库中获得了用户。


推荐