私は現在、Symfony 2.5 (および Doctrine 2.4.2) を使用して、新しいモジュール/バンドルを簡単にプラグインできるように柔軟でなければならない Web アプリケーションを設計しています。
したがって、抽象クラス(BおよびC)との2つの1対1の関連付けを持つエンティティ(Aとしましょう)があります。将来のモジュールは、2 つの抽象クラスのいずれかを実装します。アソシエーションは 1 対 1 であるため、A のインスタンスの ID がわかっている場合に簡単にアクセスできるように、それらを抽象クラスの ID にしました。
コードは次のようになります。
クラスA:
<?php
namespace Me\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity
*/
class A
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="B", cascade={"all"}, mappedBy="a")
* @ORM\JoinColumn(name="id", referencedColumnName="a_id")
*/
private $b;
/**
* @ORM\OneToOne(targetEntity="C", cascade={"all"}, mappedBy="a")
* @ORM\JoinColumn(name="id", referencedColumnName="a_id")
*/
private $c;
}
クラス B:
<?php
namespace Me\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
*/
abstract class B
{
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="A", inversedBy="b")
* @ORM\JoinColumn(name="a_id", referencedColumnName="id")
*/
private $a;
}
クラス B と同じなので、クラス C のコードは掲載しません。
私の観点では、それはすべて良いようです。マッピング検証コマンドでも。実際、 を実行するphp app/console doctrine:schema:validate
と、スキーマが有効であることがわかります。ただし、このコマンドは自分のスキーマをデータベース内のスキーマと比較しようとしますが、その時点で失敗します。php app/console doctrine:schema:update --dump-sql
まったく同じように失敗します。したがって、スキーマは有効であるが適切に使用できないことが示されるので、かなり恥ずかしいです。
エラー:
[ErrorException]
警告: array_keys() は、パラメーター 1 が配列であることを期待します。null は /vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php 行 95 で指定されます
InheritanceType および DiscriminatorColumn アノテーションをクラス B および C に追加するとすぐに、エラーが表示されます。つまり、スキーマが有効であることがわかります。
それで、私が何か間違ったことをしているなら、誰にも手がかりがありますか? それとも間違いなく Doctrine のバグですか? 私の現在のソリューションと少なくとも同じくらいの柔軟性をもたらす他のアイデアはありますか?
エリート
編集:ドキュメントによると、所有側は外部キーを持つ側であり、inversedBy 属性を使用する必要があるため、所有側を抽象クラス B および C に変更しました。これらの変更を行っても、スキーマは有効であり、同じエラーが引き続き発生します。
EDIT2: 1 対 1 の関連付けではなくエンティティの ID を保持するために B (および C) に別のフィールドを作成すると、エラーは消えますが、有効なスキーマとは異なります。
編集 3: Doctrine の開発チームのメンバーとチャットしたところ、彼は間違いなくバグのようだと言いました。バグレポートはこちら。