新实体未持久化STATE_MANAGED

时间:2017-08-08 19:00:40

标签: doctrine-orm

我试图坚持一个实体并且它不起作用。在我的测试设置中,我能够成功地保留其中一个条目。但在实际代码中,它并不是持久的。所以我深深地投入到代码中,我发现虽然在UnitOfWork.php中持久存在,但是在$entityState = $this->getEntityState($entity, self::STATE_NEW);中,下面的行在每种情况下返回不同的东西:

switch ($entityState) {

case self::STATE_NEW:

工作回报:2case self::STATE_MANAGED:

不工作返回:1public static function createAuthorizationCode(string $authorizationCodeHash, Client $client, DateTime $expires) { $authorizationCode = new AuthorizationCode(); $authorizationCode->setAuthorizationCodeHash($authorizationCodeHash); $authorizationCode->setClient($client); $authorizationCode->setExpires($expires); self::getEntityManager()->persist($authorizationCode); return $authorizationCode; }

但是,不工作的代码应该是新的。

工作:

public function setAuthorizationCode(AuthorizationCode $authorizationCode, string $authorizationCodeHash, Client $client, User $user, $redirectUri, DateTime $expires, $scope, $idToken)
{
    $authorizationCode->setAuthorizationCodeHash($authorizationCodeHash);
    $authorizationCode->setClient($client);
    $authorizationCode->setUser($user);
    $authorizationCode->setRedirectUri($redirectUri);
    $authorizationCode->setExpires($expires);
    if($scope)
        $authorizationCode->setScope($scope);
    if ($idToken)
        $authorizationCode->setIdToken($idToken);
    $this->em->persist($authorizationCode);
    $this->em->flush();
}

不工作:

public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null, $id_token = null)
{
    try {
        $authorizationCode = $this->authorizationCodeRepository->getAuthorizationCode($code);
    } catch (AuthorizationCodeNotFoundException $e) {
        //this line is hit for sure and an empty object is being
        //passed into setAuthorizationCode
        $authorizationCode = new AuthorizationCode();
    }

    $oScope = $scope ? $this->scopeRepository->getScopeById($scope) : null;

    $this->authorizationCodeRepository->setAuthorizationCode(
        $authorizationCode,
        $code,
        $this->clientRepository->getClientById($client_id),
        $this->userRepository->getUserByUserName($user_id),
        $redirect_uri,
        self::timeStampToDateTime($expires),
        $oScope,
        $id_token);

    return true;
}

不工作的来电者:

<?php
namespace PIAuth\Entity\AccessToken;

use PIAuth\Entity\Client\Client;
use PIAuth\Entity\Scope\Scope;
use PIAuth\Entity\User\User;
use DateTime;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class AccessToken
{
    public function __construct()
    {
        $this->deleted = false;
    }

    /**
     * @ORM\Id
     * @ORM\Column(type="string", unique=true, length=40, nullable=false)
     * @var string
     */
    protected $accessTokenHash;

    /**
     * @ORM\Column(type="string", length=80, nullable=true)
     * @var string
     */
    protected $idToken;

    /**
     * @ORM\Column(type="boolean")
     * @var bool
     */
    protected $deleted;

    /**
     * @ORM\ManyToOne(targetEntity="PIAuth\Entity\Client\Client")
     * @ORM\JoinColumn(referencedColumnName="clientId")
     * @var Client
     */
    protected $client;

    /**
     * @ORM\ManyToOne(targetEntity="PIAuth\Entity\User\User")
     * @ORM\JoinColumn(referencedColumnName="userName")
     * @var User
     */
    protected $user;

    /**
     * @ORM\Column(type="datetime")
     * @var DateTime
     */
    protected $expires;

    /**
     * @ORM\ManyToOne(targetEntity="PIAuth\Entity\Scope\Scope")
     * @ORM\JoinColumn(referencedColumnName="scope")
     * @var Scope
     */
    protected $scope;

    /**
     * @return string
     */
    public function getAccessTokenHash(): string
    {
        return $this->accessTokenHash;
    }

    /**
     * @param string $accessTokenHash
     */
    public function setAccessTokenHash(string $accessTokenHash)
    {
        $this->accessTokenHash = $accessTokenHash;
    }

    /**
     * @return Client
     */
    public function getClient()
    {
        return $this->client;
    }

    /**
     * @param Client $client
     */
    public function setClient(Client $client)
    {
        $this->client = $client;
    }

    /**
     * @return User
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * @param User $user
     */
    public function setUser(User $user)
    {
        $this->user = $user;
    }

    /**
     * @return DateTime
     */
    public function getExpires(): DateTime
    {
        return $this->expires;
    }

    /**
     * @param DateTime $expires
     */
    public function setExpires(DateTime $expires)
    {
        $this->expires = $expires;
    }

    /**
     * @return Scope
     */
    public function getScope()
    {
        return $this->scope;
    }

    /**
     * @param Scope $scope
     */
    public function setScope(Scope $scope)
    {
        $this->scope = $scope;
    }

    /**
     * @return mixed
     */
    public function getIdToken()
    {
        return $this->idToken;
    }

    /**
     * @param mixed $idToken
     */
    public function setIdToken($idToken)
    {
        $this->idToken = $idToken;
    }

    /**
     * @return bool
     */
    public function isDeleted(): bool
    {
        return $this->deleted;
    }

    /**
     * @param bool $deleted
     */
    public function setDeleted(bool $deleted)
    {
        $this->deleted = $deleted;
    }
}

型号:

dbus_message_new_signal()

2 个答案:

答案 0 :(得分:0)

您的AuthorizationCodeNotFoundException似乎没有被捕获。您是否在同一名称空间中,或者您有use吗?

尝试在catch块中插入die(1)以查看它是否已执行。

答案 1 :(得分:0)

哇。这个是一个令人头疼的问题。问题是Doctrine如何将实体标记为持久化。 使用spl-object-hash http://php.net/manual/en/function.spl-object-hash.php

问题是破坏数据库并在每个测试需要完成的同一过程中重新创建它。你会看到文档中的一个注释说明,

  

请注意,对象的内容(属性)不是由函数散列的,而只是其内部句柄和处理程序表指针。这足以保证同时驻留在内存中的任何两个对象将具有不同的哈希值。不同时驻留在内存中的对象之间不保证唯一性,例如:

     

var_dump(spl_object_hash(new stdClass()),spl_object_hash(new stdClass()));

     

单独运行它通常会产生相同的哈希值,因为PHP在第一个stdClass被解除引用并在创建第二个stdClass时被销毁后重用它的内部句柄。

这就是原因。 Doctine认为我的新实体是一个已经被哈希过的实体。

解决方法是创建一个新的EntityManager。希望这能帮助一些可怜的人。不要害怕深入研究代码。