2016-05-06 7 views
2

Symfony(Doctrineとの)で多対多の関係を使用して奇妙な問題が発生しました。 symfonyのプロジェクトで多対多の関係があり、私は他のプロジェクトとの違いを見つけることができません。Doctrine flush()エラー: "Doctrine Common Collections Collection | array"タイプの期待値

私は2つのエンティティのProductとTagと、多対多の関係を持っています。残念ながら、タグに商品を追加しようとすると、その商品のタグに商品を追加しようとすると、エラー

Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "TestBundle\Entity\Product#$tags", got "TestBundle\Entity\Tag" instead.

が表示されます。 製品にタグを追加するために使用されるコード:もちろん

$tag1 = $em->getRepository('TestBundle:Tag')->findOneBy(array(
     'tag' => "Bla" 
    )); 

    $tag1->addProduct($product); 
    $em->persist($tag1); 
    $em->persist($product); 

    $em->flush(); 

、変数$ TAG1と$製品の両方の有効なエンティティが含まれています。 多対多の関係(私は離れて無関係な部分をカットする)ためのYAMLファイル:

TestBundle\Entity\Tag: 
type: entity 
table: tags 
repositoryClass: TestBundle\Repository\TagRepository 
id: 
    id: 
     type: integer 
     id: true 
     generator: 
      strategy: AUTO 
fields: 
    tag: 
     type: string 
     length: 255 
     unique: true 
manyToMany: 
    products: 
     targetEntity: Product 
     mappedBy: tags 
lifecycleCallbacks: { } 

製品:

TestBundle\Entity\Product: 
type: entity 
table: products 
repositoryClass: TestBundle\Repository\ProductRepository 
id: 
    id: 
     type: integer 
     id: true 
     generator: 
      strategy: AUTO 
fields: 
    name: 
     type: string 
     length: 255 
     unique: true 
manyToOne: 
    manufacturer: 
     targetEntity: Manufacturer 
     inversedBy: products 
     joinColumn: 
      name: manufacturer_id 
      referencedColumnName: id 
      onDelete: CASCADE 
manyToMany: 
    tags: 
     targetEntity: Product 
     inversedBy: products 
     joinTable: 
      name: tags2products 
      joinColumns: 
       tag_id: 
        referencedColumnName: id 
      inverseJoinColumns: 
       product_id: 
        referencedColumnName: id 
lifecycleCallbacks: { } 

セッターとゲッター機能も特別なトリックが含まれていません。 Tag.php実体ファイルが含まれています

/** 
* Constructor 
*/ 
public function __construct() 
{ 
    $this->product = new \Doctrine\Common\Collections\ArrayCollection(); 
} 

/** 
* Add product 
* 
* @param \TestBundle\Entity\Product $product 
* 
* @return Tag 
*/ 
public function addProduct(\TestBundle\Entity\Product $product) 
{ 
    $product->addTag($this); 
    $this->product[] = $product; 
    return $this; 
} 


public function removeProduct(\TestBundle\Entity\Product $product) 
{ 
    $this->product->removeElement($product); 
} 

/** 
* Get products 
* 
* @return \Doctrine\Common\Collections\Collection 
*/ 
public function getProducts() 
{ 
    return $this->products; 
} 

をProduct.phpが含まれていますが:

/** 
* Add tag 
* 
* @param \TestBundle\Entity\Tag $tag 
* 
* @return Product 
*/ 
public function addTag(Tag $tag) 
{ 
    $this->tags->add($tag); 
    //$this->tags[] = $tag; 
    return $this; 
} 

/** 
* Remove tag 
* 
* @param \TestBundle\Entity\Tag $webpage 
*/ 

public function removeTag(Tag $tag) 
{ 
    $this->tags->removeElement($tag) ; 
} 

/** 
* Get webpages 
* 
* @return \Doctrine\Common\Collections\Collection 
*/ 
public function getTags() 
{ 
    return $this->tags; 
} 

また、$ this-> tags = new ArrayCollection();を追加しようとしました。製品のコンストラクタに渡したが、何も変更しなかった。

また、製品にタグを追加、読み取り、永続化することは問題ありません。 $ em-> flush()を呼び出すとエラーがスローされます。

私のProductエンティティがアレイコレクションを期待している理由は誰にも分かりますか?私は彼に1つを期待するように言わなかった!事前にどうもありがとうございました!

答えて

0

私はついに奇妙な問題が何かを知りました。私のエンティティを追加しようとした方法を確認してくれてありがとう、Alexandr Cosoiに感謝します。 問題は私が気付かなかった構成エラーでした。

manyToMany: 
tags: 
    targetEntity: Product 
    inversedBy: products 
    joinTable: 
     name: tags2products 
     joinColumns: 
      tag_id: 
       referencedColumnName: id 
     inverseJoinColumns: 
      product_id: 
       referencedColumnName: id 

targetEntityがProductに設定されましたが、「Tag」に設定する必要がありました。それを変更するだけで、私の問題は期待通りに解決されました。:)

+0

こんにちは、あなたは昨日質問に答えませんでしたが、これは設定の問題だったので、例外はさらに奇妙です...そして、あなたのデバッグの出力は正しいので、さらに混乱を招きます:))Doctrine \ ORM \ PersistentCollectionは正しいです。これは、sqlからデータを取得するときにdoctrineによって作成されるCollectionの型です。これは、ArrayCollectionとして機能し、インスタンス要素の削除のようなイベントを発生させる追加のボーナスを与えます。とにかくあなたはそれを理解してうれしいです。 –

2

エラーは、フラッシュしようとしているエンティティTestBundle \ Entity \ Productのプロパティ "#tags"に、このオブジェクトのコレクションではなくタイプTestBundle \ Entity \ Tagのオブジェクトが含まれていることを示しています。 Doctrineは、このプロパティのメタデータには、TestBundle \ Entity \ ProductがTestBundle \ Entity \ Tagで多数存在し、その関係がプロパティ "#tags"で行われるため、このコレクション/配列が必要です。これは次の場合に発生します:

//You did this 
$this->tags = $tag; 

//instead of what you actually did which is correct 
$this->tags->add($tag); 

//Or 

$this->tags[] = $tag; 

ただし、ここに投稿したコードでは例外が発生しません。

TestBundle \ Entity \ Productのタグプロパティを変更するアクセサメソッドが呼び出される場所は他にありませんか?イベントリスナーのようなもの?

+0

setterにコードを追加して、setterが実行され、内部で何が起こるかを確認しました。 'code' echo get_class($ this-> tags); echo get_class($ tag); このコードは以下を返します。 Doctrine \ ORM \ PersistentCollection PretiumBundle \ Entity \ Tag したがって、どちらのタイプも正しいタイプです。どのようなエラーが発生しているのかをどのようにして知ることができますか?手動でコレクションに変換する方法はありますか? –

関連する問題