2015-10-13 70 views
2

當我試圖讓這兩個實體我得到這個錯誤之間的一對多單向關聯,當我嘗試更新數據庫模式:主義要求的mappedBy在一對多單向關聯

$應用程序/控制檯學說:架構:更新--dump-SQL

[學說\ ORM \映射\ MappingException]
上字段 '地址' 一對多映射需要 '的mappedBy' 屬性。

/** 
* User 
* 
* @ORM\Table() 
* @ORM\Entity 
*/ 
class User 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\OneToMany(targetEntity="Address") 
    * @ORM\JoinTable(name="users_address", 
    *  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id", unique=true)} 
    *  ) 
    */ 
    private $address; 

    //... 
} 

/** 
* Address 
* 
* @ORM\Table() 
* @ORM\Entity 
*/ 
class Address 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    // ... 
} 

如果關聯是單向爲什麼 「的mappedBy」 要求? 在此先感謝。

UPDATE:就像由@tchap一個單向一對多可以用@ManyToMany和連接列上強制執行一對多基數的一個獨特的約束被映射在註釋中。正如文檔所述,但對我來說有點令人困惑,因爲已經有@OneToMay註釋。所以我只需要改變上面的代碼本(僅通過改變@OneToMany到@ManyToMany):

/** 
* @ORM\ManyToMany(targetEntity="Address") 
* @ORM\JoinTable(name="users_address", 
*  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id", unique=true)} 
*) 
*/ 
private $address; 
+0

我真的不明白爲什麼你想爲* OneToMany *關聯添加一個* JoinTable *,但我可能會錯過什麼? – tchap

+0

沒有具體的。我只是在學習教義。 – mevqz

+0

然後你可以放棄它我猜。 OneToMany關聯默認也是雙向的,所以你需要'mappedBy'和'inversedBy',參見https://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/association-mapping。 HTML#一個一對多的雙向。你的單向* OneToMany *只是一個* ManyToMany *僞裝 – tchap

回答

7

一個OneToMany必須是雙向的,始終是一個關係的另一方,如果你使用mappedBy屬性定義您需要指向擁有的反面。擁有方是ManyToOne。在你的情況,這將是這樣的:

User您的協會有一個mappedBy="user"屬性並指向擁有方Address

/** ONE-TO-MANY BIDIRECTIONAL, INVERSE SIDE 
* @var Collection 
* @ORM\OneToMany(targetEntity="Address", mappedBy="user") 
*/ 
protected $addresses; 

Address您的協會有一個inversedBy="addresses"屬性並指向反側User

/** MANY-TO-ONE BIDIRECTIONAL, OWNING SIDE 
* @var User 
* @ORM\ManyToOne(targetEntity="User", inversedBy="addresses") 
* @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
*/ 
protected $user; 

你可以找到哪些用戶擁有Address做:$address->getUser();,您可以跳過將額外的連接列添加到數據庫。


如果你希望關係是單向的,你可以像你在更新中那樣做;定義與連接表的ManyToMany關係,並在address_id列上添加唯一約束。

/** 
* @ORM\ManyToMany(targetEntity="Address") 
* @ORM\JoinTable(name="user_address", 
*  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id", unique=true)} 
*) 
*/ 

這種解決方案的缺點是,你不能找出User擁有從Address資源地址(Address沒有意識到User的)。這樣的例子也可以在here in the Doctrine documentation chapter 5.6. One-To-Many, Unidirectional with Join Table找到。

+0

謝謝。你有一個錯誤的擁有方(它應該是ManyToOne而不是OneToMany),但這是正確的答案。 – mevqz

+0

@mevqz oops,修正了它:P – Wilt

+0

@Wilt在你的最後一個例子中,我想你說的是用戶實體,因爲目標實體是地址。有一個錯字,address_id的unique = true屬性在inverseJoinColumns中,而不是joinColumns :) – Azuli42