我有一个问题,即Doctrine因为实体和变化的自动跟踪而在某种程度上令人讨厌。我有一个UserManager
从表单中获取新用户的数据,并将数据发送到后端,后端创建相应的数据库条目。由于后端只插入一些基本数据,如用户名,我希望保留其他所有内容,例如通过表单给出的用户角色集合。
所以我的方法应该是这样的:
public function create(User $user)
{
$this->createUserInBackend($user);
$this->em->merge($user);
$this->em->persist($user);
$this->em->flush();
}
我现在的问题是,Doctrine会从给定的$user
中删除数据,并将其替换为数据库内容。这样我就失去了所选择的用户角色。如果没有merge()
主义,则尝试INSERT
,这显然不是我想要的。
我尝试在合并,克隆或其他任何内容之前获取托管副本时,我想到了一切。在所有情况下,对象都是链接的,所以我丢失了表单中的数据(虽然它们的spl_object_hash不同)。
根据要求提供了一些更简化的细节:
class User
{
// Username is tracked by backend
private $username;
// Fullname is only tracked by frontend/Doctrine
private $fullname;
}
变式1:
public function create(User $user)
{
// The user entity gets passed to the backend, which does some stuff
// and also inserts the entity in the database.
$this->createUserInBackend($user);
// The entitiy is in the database, but not managed by the EM.
// Therefore Doctrine does an INSERT.
$this->em->persist($user);
$this->em->flush();
}
变式2:
public function create(User $user)
{
// The user entity gets passed to the backend, which does some stuff
// and also inserts the entity in the database.
$this->createUserInBackend($user);
// Now there's an entity in the db with ID and username, but not the fullname
$user = $this->em->merge($user);
// The merge finds the entry in the database and refreshes its data.
// This leads to $user->fullname which was given in the form to be emptied. :(
$this->em->persist($user);
$this->em->flush();
}
我还尝试将merge
的返回值放入$otherUser
变量,但对象已关联且fullname
仍然被删除。
我只需要告诉Doctrine新实体是管理的,但它不应该触及它的数据。我已经研究了潜在的UnitOfWork
,但找不到解决这个问题的技巧。