2012-10-28 180 views
2

我有一個用戶實體。這被認爲是這種情況下的主要實體,它被使用的事實意味着它存在。實體之間的可選OneToOne關係?

用戶實體擁有一個Store實體。但並非所有用戶都必須擁有Store實體。

值得注意的是,這是我們正在使用的現有數據庫,並且User表的id與Store表的id相同。名稱(id)和值。只是在某些情況下,Store沒有給定用戶標識的記錄。

用戶:

class User extends Entity 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="string", length=36) 
    */ 
    protected $id; 

    /** 
    * @ORM\OneToOne(targetEntity="Store") 
    * @ORM\JoinColumn(name="id", referencedColumnName="id") 
    */ 
    protected $store; 

    ... 
} 

商店:

class Store extends Entity 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="string", length=36) 
    */ 
    protected $id; 

    ... 
} 

這會導致控制器的問題。如果用戶實體沒有存儲記錄,則會失敗並顯示「未找到實體」異常。這可以使用一個try catch來處理,這很容易(我還沒有找到一種方法來檢查一個實體對象是否存在或者只是一個代理)。如果用戶確實有商店記錄,這裏一切都很好。

但最大的問題,我有特別的燈具:

protected function createUser($id) 
{ 
    $user = new User(); 
    $user->setId($id); 
    $user->setEmail($id.'@example.com'); 
    $user->setUserName($id.'_name'); 
    $user->setArea($this->manager->find('Area', 156)); // Global 

    $this->manager->persist($user); 

    return $user; 
} 

當我運行燈具,失敗。給我錯誤「完整性約束違規:1048列'id'不能爲空」。如果我從用戶中刪除商店實體,此消息將消失。所以簡而言之,如果用戶沒有商店,我無法添加用戶。

任何人都知道發生了什麼?我已經做了一些四處尋找,我找不到任何東西,包括教義文檔,有實體之間的可選關係。我認爲這是一種常見的情況。

回答

1

發現這個文檔頁面上的解決方案,這一點:

http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-3-join-table-with-metadata

在我的情況,而不是用戶實體正在使用的ID字段,在用戶實體店物業的商店實體相關聯將被用戶(一個實體對象)關聯到Store實體。作爲回報,Store對象將持有一個用戶實體,該實體被註釋爲實體的ID。

我敢肯定這就像地獄一樣令人困惑,所以看看上面的示例吧。下面是我的調整實體類:

用戶

class User extends Entity 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="string", length=36) 
    */ 
    protected $id; 

    /** 
    * @ORM\OneToOne(targetEntity="Store", mappedBy="user") 
    */ 
    protected $store; 

    ... 
} 

商店

class Store extends Entity 
{ 
    /** 
    * @ORM\Column(type="string", length=36) 
    */ 
    protected $id; 

    /** 
    * @ORM\Id 
    * @ORM\OneToOne(targetEntity="User") 
    * @ORM\JoinColumn(name="id", referencedColumnName="id") 
    */ 
    protected $user; 

    ... 
} 

現在,如果不存在一個給定用戶存儲記錄,在用戶實體店物業會空值。賽程也按預期運行。

0

除了上面的答案,我還需要添加一個inversedBy屬性。否則,將拋出無效的實體映射錯誤。

使用上述實體的Store對象需要是這樣的:

class Store extends Entity 
{ 
/** 
* @ORM\Column(type="string", length=36) 
*/ 
protected $id; 

/** 
* @ORM\Id 
* @ORM\OneToOne(targetEntity="User", inversedBy="store") 
* @ORM\JoinColumn(name="id", referencedColumnName="id") 
*/ 
protected $user; 

... 
}