2014-10-02 72 views
3

我有一個名爲「Order」的Doctrine2實體,它有幾個狀態屬性。 「允許狀態」存儲在不同的實體中,因此爲這些實體定義了ManyToOne關係。ManyToOne關係屬性的Doctrine2實體默認值

/** 
* @ORM\Entity() 
*/ 
class Order extends AbstractEntity { 
    // ... 
    /** 
    * @ORM\ManyToOne(targetEntity="Status") 
    * @ORM\JoinColumn(onDelete="NO ACTION", nullable=false) 
    */ 
    protected $status; 

    /** @ORM\Column(nullable=true) */ 
    protected $stringProperty = "default value"; 

} 

當創建訂單對象的新實例時,我需要將此狀態屬性設置爲默認值。

對於「非關係」屬性,我可以簡單地將它設置爲像上面的$ stringProperty。但如何爲關係做呢?

  • 由於Doctrine2會投訴,我無法將該值設置爲相關記錄的ID。
  • 這很好,如果配置的默認是「參考」的狀態實體。可用狀態'是固定的,並且不會改變(經常)。

如何配置實體以配置正確的默認關係。

最好不要在監聽器中持續存在,因爲在此之前可能會請求狀態。

回答

3

有幾種方法,但我會建議使用OrderRepository作爲創建新訂單的工廠。

class OrderRepository 
{ 
    public function create() 
    { 
     $order = new Order(); 
     $status = $this->_em->find('Status','default'); // or getReference 
     $order->setStatus($status); 
     return $order; 
    } 
} 

// In a controller 
$orderRepository = $this->container->get('order_repository'); 
$order = $orderRepository->create(); 

通過使用存儲庫,您可以初始化複雜的實體圖形,這些圖形將爲持久化做好準備。

============================================== ============================

計劃B將做這種事情的順序對象,然後使用偵聽器在堅持或更新之前「解決問題」。

class Order 
{ 
    public function __construct() 
    { 
     $this->status = new Status('Default'); 
    } 
} 

問題當然是數據庫中已經存在一個默認的狀態對象,所以當你刷新時你會得到一個錯誤。因此,您需要在實體管理器上掛一個onFlush(http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#onflush)偵聽器,檢查狀態對象是否由實體管理器管理,如果不是,則將其替換爲通過實體管理器獲取的管理對象。

這種方法可以讓你處理更多的「純」域模型,而不用擔心持久層。另一方面,處理沖洗可能會很棘手。在抓握的手上,一旦你得到它的工作,然後它確實打開了一些主要的可能性。

============================================== ==========

還有一個問題,究竟是什麼狀態實體。如果它包含的是一些狀態狀態('進入','已處理')等等。那麼你可能會考慮把它當作一個字符串。有點像ROLE_USER對象。

+0

簡單但非常有效的解決方案。爲什麼我沒有想到這一點。我正在考慮創建一個單獨的服務,但這感覺很奇怪和矯枉過正。這保持了創建新的邏輯並找到現有的實體。 – DoppyNL 2014-10-03 08:54:54

+0

您是否恰好對訂單內部需要更改狀態(到另一個實體)的情況有所建議? – DoppyNL 2014-10-03 08:55:42