2012-05-11 13 views
4

私はこのエラーを検索しようとしましたが、何も見つからなかったという事実は私が愚かなことをしていると信じています。以下の関連するコードを追加しますが、基本的には複数のテーブル継承(またはClass Table Inheritance)を使用しており、Discriminator列に基づいてDoctrine ORM findBy()メソッドを使用して、次のORMExceptionがスローされます。 "認識されないフィールド:タイプ"。ここでDoctrine2.1:DiscriminatorColumnの結果が「Unknown field」例外になります

は、例外をトリガコードです:ここでは

// $this->em is an instance of \Doctrine\ORM\EntityManager 
    $repository = $this->em->getRepository('JoeCommentBundle:Thread'); 

    return $repository->findOneBy(array(
     'type' => $this->type, 
     'related_id' => $id 
    )); 

は「ベース」抽象エンティティに関連するコードです:

<?php 

namespace Joe\Bundle\CommentBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Gedmo\Mapping\Annotation as Gedmo; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* @ORM\Entity 
* @ORM\Table(name="comment_threads") 
* @ORM\InheritanceType("JOINED") 
* @ORM\DiscriminatorColumn(name="type", type="string") 
* @ORM\DiscriminatorMap({"story" = "Joe\Bundle\StoryBundle\Entity\StoryThread"}) 
*/ 
abstract class Thread 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(name="related_id", type="integer") 
    */ 
    protected $relatedId; 

    /** MORE FIELDS BELOW.... **/ 

そして最後に、ここではコンクリート用のコードですスレッドエンティティ:

<?php 

namespace Joe\Bundle\StoryBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Joe\Bundle\CommentBundle\Entity\Thread as AbstractThread; 

/** 
* @ORM\Entity 
* @ORM\Table(name="story_comment_threads") 
*/ 
class StoryThread extends AbstractThread 
{ 
    /** 
    * @ORM\OneToOne(targetEntity="Story") 
    * @ORM\JoinColumn(name="story_id", referencedColumnName="id") 
    */ 
    protected $story; 
} 

私のスキーマをダブルチェックしました。typeの列は間違いなく存在するので、何が原因か分かりません。何か案は?ありがとう。

+0

Doctrineはあなたのための列を「入力」というマッピングの世話をする必要があります。私はそれが予約されているキーワードで、多分いくつかの問題を引き起こしているのだろうかと思います。他のものに変更して、まだ問題が発生していないかどうかを確認してください。 –

+1

Leeさんに感謝しますが、それを "thread_type"に変更しても差はありません。幸いにも、これは私のローカルxdebugを修正するように強制され、私は今、Doctrine \ ORM \ Persisters \ BasicEntityPersisterに1205行目のチェックがあるのを見ることができます: "if(isset($ this - > _ class-> columnNames [$フィールド]))"。 $ this-> _class-> columnNames配列には、( 'type'または 'thread_type'として)差別的な列は含まれていませんが、後で詳細を含む$ this-> _ class-> discriminatorColumn配列があります。それは考慮されていないので、Doctrineのバグですか? – RobMasters

+0

私はもう少し掘り下げて、ほぼ2年前から次の問題報告を見つけました:[http://www.doctrine-project.org/jira/browse/DDC-707](http://www.doctrine -project.org/jira/browse/DDC-707)解決されたバグの重複としてマークされていますが、実際の問題は見落とされていると思います。 – RobMasters

答えて

14

実際に親エンティティを使用して照会し、弁別子の値をフィルタリングしようとしているとき。代わりに、フェッチしたい子エンティティを基準にリポジトリを操作します。 Doctrineはあなたのために残りをします。あなたのケースでは、StoryThreadのリポジトリを取得したいと考えています。

$repository = $this->em->getRepository('JoeCommentBundle:StoryThread'); 
return repository->find($id); 
+0

それはトリックでした! :) – RobMasters

10

標準エンティティプロパティとして、ディスクリミネータ列を使用することはできません。

代わりに、あなたは次の操作を行うことがあります。

$dql = 'SELECT e FROM JoeCommentBundle:Thread e 
    WHERE e.related_id = :related_id AND e INSTANCE OF :type'; 
$query = $em->createQuery($dql); 
$query->setParameters(array(
    'type' => $this->type, 
    'related_id' => $id 
)); 
$record = $query->getSingleResult(); 
+1

ああ、私はそれを念頭に置いておくことを確認します。しかし、関連するリポジトリのfindメソッドを使用する方が簡単でした。 – RobMasters

+0

時にはそれでは不十分です。たとえば、2つのエンティティタイプのうち2つを選択するか、そのタイプで順序を選択する必要がある場合などです。 – Gedrox

+4

FYI: 'INSTANCE OF(:type1、:type2、...) 'を使って複数の型を選択できるので、結果に含めるクラスごとに複数の' INSTANCE OF'関数呼び出しを連結する必要はありません。 – flu

関連する問題