2017-08-08 77 views
0

我试图坚持一个实体,它不工作。在我的测试设置中,我能够成功保留其中一个条目。但在实际的代码中,这并不是持久的。所以,我深深一头扎进了代码,我发现,虽然坚持,在坚持不工作,在UnitOfWork.php,下面一行将返回的东西在每种情况下不同:新实体不持久STATE_MANAGED

$entityState = $this->getEntityState($entity, self::STATE_NEW);

switch ($entityState) {

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

不工作的回报:case self::STATE_MANAGED:1

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

工作:

public 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; 
    } 
} 

回答

0

看来你的AuthorizationCodeNotFoundException没有捕捉到。你在相同的命名空间,或者你有任何use吗?

尝试插入在catch块die(1),看它是否得到执行。

+0

它与例外无关。我回答了我自己的问题。 – Bluebaron

+0

@Bluebaron在你的问题中你没有提到它...... – ste

0

哇。这是一个头痛的人。问题在于教义如何将实体标记为坚持。 使用spl-object-hashhttp://php.net/manual/en/function.spl-object-hash.php

问题是销毁数据库并在需要为每个测试完成的相同过程中重新创建它。你会看到,在doc音符的一个说,

注意对象的内容(属性)不通过散列函数,仅仅是其内部处理和处理程序表指针。这足以保证同时共存在内存中的任何两个对象将具有不同的哈希值。例如:

var_dump(spl_object_hash(new stdClass()),spl_object_hash(new stdClass()));对于没有同时驻留在内存中的对象之间的唯一性不保证。

单独运行通常会生成相同的哈希值,因为PHP在第一个stdClass解除引用和重新创建第二个stdClass时被重新使用内部句柄。

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

解决这也创造了新的EntityManager。希望这有助于一些可怜的灵魂。不要害怕深入代码。

+0

没有创建一个新的实体管理器,你可以在销毁你的dB后立即调用$ em-> clear()。请参阅http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#entities-and-the-identity-map。这也让你节省一些内存,因为所有先前管理的实体都会分离并且可以被垃圾回收。 – ste