2012-08-31 101 views
0

我使用的Doctrine 2.1支持通過外國實體的身份(外鍵作爲標識符)。學說2.1通過外國實體的身份一對一雙向協會

http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/tutorials/composite-primary-keys.html#identity-through-foreign-entities

是否有可能通過外國實體身份與一個雙向的關係?我想,但我得到以下錯誤,當我打開我的數據燈具:

[PDOException]

SQLSTATE [23000]:完整性約束違規:1452不能添加或更新子行:一個外鍵約束失敗(tableuser,約束FK_187DDE86BF396750外鍵(id)參考文獻addressuser_id))

這裏是我的實體:

/** 
* @Entity 
*/ 
class User 
{ 
    /** @Id @Column(type="integer") @GeneratedValue */ 
    private $id; 

    /** @OneToOne(targetEntity="Address") */ 
    private $address; 
} 

/** 
* @Entity 
*/ 
class Address 
{ 
    /** @Id @OneToOne(targetEntity="User") */ 
    private $user; 
} 

如果我刪除用戶到地址的引用,錯誤消失!

我想能夠做到以下幾點:

$address = $user->getAddress(); 

..但似乎我必須做的:

$address = $entityManager->find('Address', $user->getId()); 

是嗎?有沒有辦法做到這一點?

更新1:

我想可以設置從兩側(雙向)的關係,但是這似乎並不可能。

說實話,我不確定關係的反面點是什麼,因爲「僅對關聯反面進行的更改將被忽略」http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/association-mapping.html#owning-side-and-inverse-side

要點是什麼:

從這裏的文檔多久?

從它似乎更有意義,做應用的角度來看:

$user->setAddress($address);

而不是:

$address->setUser($user);

但是第一是不可能的可能的,因爲:

  1. 製作關係雙向制動東西
  2. User方必須是反面,所以$user->setAddress($address);將被忽略!

會有人解釋這一點,請:)

馬修

回答

0

你有沒有在您的用戶定義的實體地址字段的getter?

public function getAddress() 
{ 
    return $this->address; 
} 

請記住,該原則總是返回集合。

+0

感謝馬克斯,但那不是問題所在。是的,當我在User實體中添加$ address字段時,在User實體類中爲我生成了一個'getAddress()'方法。但是,通過User實體上的'$ address'字段,FK約束被添加到數據庫'user'表中的id列。這個FK約束停止將數據加載到數據庫中,像這樣:$ address = new Address(); $地址 - > SETUSER($用戶);'。 – mattvick

+0

我的另一個拍攝是,這個用戶有地址引用,你試圖添加另一個。 –

1

你的問題是沒有關係的「外鍵標識」,而是一個關係的擁有方:

教義,關係可以是雙向的,但在這種情況下,關係必須有一個「onwing -側」。這意味着:您的「實體部分」上的

  • :您的實體都具有相互引用的屬性。在您的情況下,您的用戶和$用戶地址中的$地址,並且您可以在「sql部分」上使用$ user-> getAddress()和$ address-> getUser()

  • :只有一個表,擁有方擁有引用另一個表的屬性。

您可以通過非擁有方使用「mappedBy」來通知Doctrin擁有哪方。 在你的情況下,使用外鍵作爲標識符,你沒有選擇:擁有方是外鍵。 所以,測試:

/** 
* @Entity 
*/ 
class User 
{ 
    /** @Id @Column(type="integer") @GeneratedValue */ 
    private $id; 

    /** @OneToOne(targetEntity="Address", mappedBy="user") */ 
    private $address; 
} 

/** 
* @Entity 
*/ 
class Address 
{ 
    /** @Id @OneToOne(targetEntity="User", inversedBy="address")) */ 
    private $user; 
} 

另一個重要的一點: 在雙向關係,當你設置非持有端主義不能automaticaly更新的另一邊。所以你必須做到manualy。對於沒有做每次創建新的用戶和地址時想一想,你可以在你的setter自動執行的過程:

// in class User : 
public function setAddress($address) { 
    $address->setUser($this);   // <= here it is !!! 
    $this->address = $address; 
    return $this; 
} 

// in class Address : 
public function setUser($user) { 
    $this->user = $user; 
    return $this; 
} 

現在,你可以設置地址,像你想,沒有理會這個所屬-副作用東西:

$address = new Addresse(); 
$address->set... 
$user->setAddress($address);