如何将当前经过身份验证的用户设置为实体中的引用

时间:2013-07-05 17:15:48

标签: symfony

我有实体提供程序(它只是实体存储库,可以在身份验证时搜索并向我提供用户),例如entity provider (MyBundle:Employee实现UserInterface,这样就可以了)

class EmployeeRepository extends EntityRepository implements UserProviderInterface
{
   public function loadUserByUsername($username)
   {
       $user = $this->getEntityManager()
        ->createQuery("SELECT e FROM MyBundle:Employee e ...")
        ->setParameters(...)->getOneOrNullResult();
        if ($user) {
            return $user;
        }

        throw new UsernameNotFoundException();
    }

    public function refreshUser(UserInterface $user)
    {
        ...

       return $this->find($user->getId());
    }
}

我有另一个实体,如

class Task {
    ...

    /**
     * @ManyToOne(targetEntity="Employee")
     * @JoinColumn()
     */
    protected $creator;

    ... + setters/getters
}

所以在控制器的某个地方我有:

$task = new Task();
$task->setCreator($this->getUser()) // or $this->get('security.context')->getToken()->getUser();
$em->persist($task);
$em->flush();

我有异常“通过关系发现了一个新实体'... \ Entity \ Task#creator'没有配置为级联实体的持久操作:... \ Entity \ Employee @ 0000000066a194ca0000000038e61044。要解决此问题:在此未知实体上显式调用EntityManager#persist()或配置级联持久性“

但它怎么可能:unperisted实体是由entityRepository给出的??? (如果持久化getUser()em尝试插入新的Employee)如何设置任务的创建者?

3 个答案:

答案 0 :(得分:1)

据我了解,您希望能够加入Task实体上的Employee实体,以便了解哪个用户创建了Task。

如果是这样,您应该查看允许您在Symfony2中轻松使用StofDoctrineExtensionBundleDoctrineExtension

DoctrineExtension提供blameable behavior

  

可责备行为将自动更新您的实体或文档上的用户名或用户参考字段。它通过注释工作,可以在创建,更新甚至特定属性值更改时更新字段。

namespace Entity;

use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Article
{
    // ...

    /**
     * @var string $createdBy
     *
     * @Gedmo\Blameable(on="create")
     * @ORM\Column(type="string")
     */
    private $createdBy;

    /**
     * @var string $updatedBy
     *
     * @Gedmo\Blameable(on="update")
     * @ORM\Column(type="string")
     */
    private $updatedBy;

    // ...

    public function getCreated()
    {
        return $this->created;
    }

    public function getUpdated()
    {
        return $this->updated;
    }
}

希望这有帮助

答案 1 :(得分:1)

我找到了解决方案。

在这段代码中我使用了实体管理器的新实例,如$ this-> get('doctrine.orm.entity_manager')

$task = new Task();
$task->setCreator($this->getUser())
$em->persist($task);
$em->flush();

,因此新的实体经理对用户

等实体一无所知

,解决方案是使用默认实体管理器

$em = $this->get('doctrine.orm.default_entity_manager');
...
$em->persist(task);
$em->flush();

工作正常。

答案 2 :(得分:0)

我看不到代码,但是如果你想同时插入新任务和新用户(使用表单中的集合类型),你需要在你的实体中定义它(级联注释):

class Task {
    ...

    /**
     * @ManyToOne(targetEntity="Employee", cascade={"persist"})
     * @JoinColumn()
     */
    protected $creator;

    ... + setters/getters
}


有关级联操作的详细信息,请参阅Doctrine文档:http://docs.doctrine-project.org/en/2.0.x/reference/working-with-associations.html#transitive-persistence-cascade-operations