Doctrine - 实体在分离会话管理后保留代理

时间:2013-06-27 05:04:43

标签: php orm doctrine-orm doctrine

上下文

我需要使用Doctrine 2.3(使用PHP 5.4)将实体保存到会话中,并且在设置$_SESSION变量后我遇到问题。

代码

我有以下课程:

Persistente

用于保存持久类信息的超类。

/**
 * @MappedSuperclass
 */
abstract class Persistente
{
    public function __construct()
    {}

    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        $this->id = $id;
    }

    /**
     * @Id
     * @GeneratedValue
     * @Column(type="integer")
     */
    protected $id;
}

假面

保存有关某人的基本信息。

/**
 * @Entity
 * @AttributeOverrides({
 *      @AttributeOverride(name="id",
 *          column=@Column(
 *              name="Persona_Id",
 *              type="integer"
 *          )
 *      )
 * })
 */
class Persona extends Persistente
{
    ...

    public function getContInformacion()
    {
        return $this->contInformacion;
    }

    public function setContInformacion(ContenedorInformacion $contInformacion)
    {
        $this->contInformacion = $contInformacion;
    }

    ...

    /**
     * @OneToOne(targetEntity="ContenedorInformacion", cascade={"all"}  )
     * @JoinColumn(name="ContInfo_Id", referencedColumnName="ContInfo_Id")
     */
    private $contInformacion;

}

ContenedorInformacion

包含人员信息的类,可以根据某些验证规则动态添加到对象中。

/**
 * @Entity
 * @AttributeOverrides({
 *      @AttributeOverride(name="id",
 *          column=@Column(
 *              name="ContInfo_Id",
 *              type="integer"
 *          )
 *      )
 * })
 */
class ContenedorInformacion extends Persistente
{
    ...

    /**
     * @OneToMany(targetEntity="UnidadInformacion", mappedBy="contInformacion", cascade={"all"}, indexBy="clave")
     */
    private $unidadesInformacion;

    /**
     * @OneToMany(targetEntity="Rol", mappedBy="contInformacion", cascade={"all"}, indexBy="clave")
     */
    private $roles;

}

问题

每当我向会话添加Persona时,都会执行以下代码:

public function login(Persona $t)
{
    if ($this->autorizar($t) === false) {
        return false;
    }
    $dao = new DAOManejadorMsSql();
    $daoPersona = $dao->fabricarDAO("\Codesin\Colegios\Personas\Persona");
    $t = $this->buscarPersona($t);
    $daoPersona->soltar($t);
    $dao->cerrar();
    $_SESSION['usuario'] = $t;
    if ($t->getContInformacion()->existeRol('SYSADMIN') === true) {
        return 'SYSADMIN';
    }
}

soltar()从EntityManager执行detach()方法,实际上使实体不受管理。但是,ContenedorInformacion中的Persona对象是由Doctrine而不是所需对象生成的代理。为什么会这样?先谢谢你。

编辑:这是错误。

Warning: require(C:\xampp\htdocs/Zeus/lib/vendor/DoctrineProxies/__CG__/Codesin/Colegios/Personas/ContenedorInformacion.php): failed to open stream: No such file or directory in C:\xampp\htdocs\Zeus\Common\Utils\autoload.php on line 8

Fatal error: require(): Failed opening required 'C:\xampp\htdocs/Zeus/lib/vendor/DoctrineProxies/__CG__/Codesin/Colegios/Personas/ContenedorInformacion.php' (include_path='.;C:\xampp\php\PEAR') in C:\xampp\htdocs\Zeus\Common\Utils\autoload.php on line 8

1 个答案:

答案 0 :(得分:0)

我不得不采用非常粗暴的方法。

我想出了以下内容:鉴于我不会立即重新附加信息,我重新构建了另一个ContenedorInformacion,其中包含与代理完全相同的信息。鉴于ArrayCollection s不是使用代理而是使用整个对象,我这样做了。

public function login(Persona $t)
{
    if ($this->autorizar($t) === false) {
        return false;
    }
    $dao = new DAOManejadorMsSql();
    $daoPersona = $dao->fabricarDAO("\Codesin\Colegios\Personas\Persona");
    $t = $this->buscarPersona($t);
    $daoPersona->soltar($t);
    $dao->cerrar();
    /***** NEW LINES START HERE *****/
    $contInfo = new ContenedorInformacion();
    $contInfo->setId($t->getContInformacion()->getId());
    $contInfo->setUnidadesInformacion(new ArrayCollection($t->getContInformacion()->getUnidadesInformacion()->toArray()));
    $contInfo->setRoles(new ArrayCollection($t->getContInformacion()->getRoles()->toArray()));
    $t->setContInformacion($contInfo);
    /***** NEW LINES END HERE *****/
    $_SESSION['usuario'] = $t;
    if ($t->getContInformacion()->existeRol('SYSADMIN') === true) {
        return 'SYSADMIN';
    }
}

它很脏,但它的功效就像一个魅力。