2016-07-29 28 views
2

に「クラス表の継承」を使用して教義と結合が多すぎる:私はsymfonyのとDoctrineで働いていると私は、次のエラーになってしまったsymfonyプロジェクト

SQLSTATE[HY000]: General error: 1116 Too many tables; MySQL can only use 61 tables in a join`

メインエンティティ(の一番上のテーブル階層)には61以上のエンティティの識別器マップが含まれています。 「多対多」の関連付けがそれ自体で行われるため、エンティティは親または子として他の人とリンクすることができます。ここで

エンティティDoctrineの注釈です:私は(さえtopclass「エンティティ」を拡張しない)いくつかの古典的なエンティティのリストを取得するにformTypeにクエリビルダを使用するたびに

/** 
* Entity 
* 
* @ORM\Table(name="entity") 
* @ORM\Entity(repositoryClass="Acme\EntityBundle\Repository\EntityRepository") 
* @InheritanceType("JOINED") 
* @DiscriminatorColumn(name="type", type="string") 
* @DiscriminatorMap({ 
*  "sub_entity_1" = "\Acme\SubEntityABundle\Entity\E1", 
*  "sub_entity_2" = "\Acme\SubEntityABundle\Entity\E2", 
*  ... 
* }) 
*/ 
class Entity 
{ 
    /** 
    * @ORM\ManyToMany(targetEntity="Entity", inversedBy="parentEntities") 
    * @ORM\JoinTable(name="rel_entity_entity", 
    * joinColumns={@ORM\JoinColumn(name="parent", referencedColumnName="id")}, 
    * inverseJoinColumns={@ORM\JoinColumn(name="child", referencedColumnName="id")} 
    *) 
    */ 
    private $childrenEntities; 

    /** 
    * @ORM\ManyToMany(targetEntity="Entity", mappedBy="childrenEntities") 
    * 
    */ 
    private $parentEntities; 

    /** 
    * Get children entities 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getChildrenEntities() 
    { 
     return $this->childrenEntities; 
    } 

    /** 
    * Set childrenEntities 
    * 
    * @param ArrayCollection $entities 
    */ 
    public function setchildrenEntities(ArrayCollection $entities) 
    { 
     $this->childrenEntities = $entities; 
    } 

    ... 
} 

、 Doctrineは、ディスクリミネータマップ内のすべてのエンティティに対して左結合を行います(そして、MySQLの一般的なエラーを生成します)。

にformType

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('childrenEntities', 'entity', array(
     'class' => 'AcmeEntityBundle:Entity', 
     'required' => false, 
     'choice_label' => 'slug', // slug is defined as a main entity's attribute 
     'query_builder' => function (EntityRepository $er) { 
      return $er->getSomeEntities(); 
     }, 
    )); 

    ... 
} 

EntityRepository

public function getSomeEntities() 
{ 
    return $this->getEntityManager() 
     ->createQueryBuilder() 
     ->select('e') 
     ->from('AcmeEntityBundle:Entity', 'e') 
     ->where('e.id IN (:ids)') 
     // Tried that, doesn't work 
     //->andWhere('e INSTANCE OF AcmeEntityBundle:Entity') 
     ->setParameter('ids', [53300, 12345]); 
} 

いずれかに参加するためにはない教義を伝える方法はありますか? 2.4

私は読んでいくつかの便利なDOC:

ありがとうございました!

答えて

0

よく、大きな問題はmysql limitationです。私はあなたがそれを要求していない場合、なぜドクトリンが左の参加をしているのか理解していません。メインエンティティに関連するデータのみが必要な場合は、次の特定のフィールドに選択を変更します。

->select('e.id, e.slug, ...') 

希望すると助かります。あなたは、基本クラスのいくつかの並べ替えし、それを拡張し、それにいくつかの非常に異なる特性を追加するクラスの束を持っているように見える

Class Table Inheritance is an inheritance mapping strategy where each class in a hierarchy is mapped to several tables.

ここでドキュメントによって

+0

私は ' - > select( 'e.id、e.slug)'を試しました。私は、DiscriminatorMap内に2つのクラス(まだ_JOINED_タイプ)のシンプルなケースでそのケースを再現しました。そして唯一の "実体" フィールドに簡単なフォームを作る: 'パブリック関数getSomeEntities(){ 戻ります$ this-> getEntityManager() - > createQueryBuilder() - >を選択し( 'e.id、e.slugを') - > from(' AcmeEntityBundle:Entity '、' e '); } ' – shabang

+0

これは変ですが、核兵器のオプションを使用することはできますか?http://doctrine2.readthedocs.io/en/latest/reference/native-sql.html#native-sql – abdiel

+0

GitHubを見てみましょう:https://github.com/doctrine/doctrine2/issues/5961 – shabang

0

私はクラステーブル継承の使用に精通していませんが、ここではその機能の設計と使用方法に違いがあるようです。

+0

私の古典的な使用例では、私は確かにあなたが言ったように(#何らかの基底クラスとそれを拡張するクラスの束いくつかの非常に異なった性質がある)。しかし、特定のユースケースでは、これらのクラスのすべてのスラッグをリストする必要もあります。スラッグは基本クラスの一部なので、私は全く異なるプロパティ_が必要なわけではありません。したがって、私はすべての自動結合のトリプルを必要としません:) – shabang

+0

それから、これらのクラスには1対1の関係スラッグクラスですが、大きな画像を見ずに言うのは少し難しいです。 –

0

あなたが壊れたように見えます。one of the main rules of Doctrine's CTI:クラス階層に所属しないように見えます。 あなたのケースでは、親子の関連付けを行っているので、Doctrineはあまりにも多くのJOINSを生成しました。それは親にすべてのあなたの子供の実体を結合しようとしました、と思います。私は同じエンティティでCTIとの親子関係を避けるべきだと思います。

関連する問題