2017-08-08 76 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