2011-07-13 6 views
1

私のオブジェクト間の関係が一貫していることを保証するのに問題があります。私はDoctrine 2を使用していますが、これはおそらく他の言語やORMマッパーにも当てはまります。オブジェクトの関係の一貫性を保証する(doctrine 2)

Doctrineによると、関係には所有側と逆側があります。双方向関係を使用する場合は、一貫性を確保する必要があります。基本的には、関係の片側が変更されたときに手動で相手側を更新する必要があります。 Foo hasMany Barここ

私の例:意図したとおりに

class Foo 
{ 
    /** @OneToMany(targetEntity="Bar",mappedBy="foo") */ 
    private $bars; 

    public function addBar($bar) 
    { 
     $this->bars[] = $bar; 
     // Ensure consistency 
     $bar->setFoo($this); 
    } 
} 

class Bar 
{ 
    /** @OneToMany(targetEntity="Foo",inversedBy="bars") */ 
    private $foo; 

    public function setFoo($foo) 
    { 
     $this->foo = $foo; 
     // Ensure consistency 
     $foo->addBar($this); 
    } 
} 

は今、明らかに、上記のコードは動作しません。 Foo::addBarまたはBar::setFooが呼び出されると、無限ループになります。だから、どうすればFooBarになるはずですか?中

ユーザー/バグ例ドクトリン2 「はじめに」ガイドは、単にだけsetFooaddBarに一貫性を保証していないことで問題を回避スカート。

私が遭遇している壁は、addBarsetFooの両方が公開関数でなければならない、または私は関連モデルから呼び出すことができないということです。しかし、これは、これらのオブジェクトを使用する開発者がいずれかの関数を使用して新しい関係を作成できることを意味します。

どうすれば解決できますか?どのように他の言語やマッパーがこれを解決するのですか?

答えて

2

これまでの私のアプローチです。ちょっとした小切手を追加しました

class Foo 
{ 
    /** @OneToMany(targetEntity="Bar",mappedBy="foo") */ 
    private $bars; 

    public function addBar($bar) 
    { 
     if (!$this->bars->contain($bar)) { 
      $this->bars[] = $bar; 
      $bar->setFoo($this); 
     } 
    } 
} 

class Bar 
{ 
    /** @OneToMany(targetEntity="Foo",inversedBy="bars") */ 
    private $foo; 

    public function setFoo($foo) 
    { 
     if ($this->foo !== $foo) { 
      $this->foo = $foo; 
      $foo->addBar($this); 
     } 
    } 
} 
2

私は基本的教義2で、このようにこれを解決する方法を他のマッパーか分からない...彼らはマニュアルの「所有する側」について話すとき

が、彼らはエンティティあなたのコードを参照してください。常にオブジェクトを関連付けるために使用する必要があります。

これは主に、セマンティック決定である:たとえば、あなたが車やタイヤを持っている場合、それはタイヤが車$car->addTire($tire);と車に追加されていることを理にかなっては、タイヤに追加されていない$tire->setCar($car);

だから何所有者が行うべきことは、関係の一貫性を保証することです。 「所有していない」側は関連プロパティを設定するだけです。

コードが正しくない場合、は所有していない側を使用しているため、関係が矛盾する可能性があります。ただし、これはスクリプトの実行中にのみ問題になります。リレーションを両端で設定しなくても、DBに正しく格納されるため、次にデータがフェッチされると、エンティティ間で一貫した方法でセットアップされます。

+0

いいえ。しかし、基本的に誰かが間違った(逆の)側から関係に追加するのを防ぐ方法はありませんか? –

+0

私の知る限り - いいえ。あなたのリポジトリに、他のapprochを使用している人と比較して使うべきfindメソッドを持っているのであれば、ちょっと似た問題です。ドキュメントを提供することやそれを説明すること以外に、実際にそれを防ぐことはできません。 –

関連する問題