2016-05-06 5 views
2

Ich habe ein seltsames Problem mit einer Viele-zu-Viele-Beziehung in Symfony (mit Doctrine), die ich noch nie zuvor hatte in Symfony-Projekten mit vielen-zu-vielen Beziehungen und ich finde keinen Unterschied zu den anderen Projekten.Doctrine flush() error: Erwarteter Wert vom Typ "Doctrine Common Collections Collection | array"

Ich habe die beiden Entitäten Produkt und Tag und eine Viele-zu-viele-Beziehung zueinander. Wenn ich versuche, ein Produkt zu einem Tag hinzuzufügen oder umgekehrt, wird der Fehler

angezeigt. Der Code verwendet, um einen Tag zu einem Produkt hinzuzufügen:

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

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

    $em->flush(); 

Natürlich ist die Variable $ tag1 und $ beide Produkt eine gültige Einheit enthalten. (Irrelevant Teile I wegschneiden) Die YAML-Datei für die many-to-many-Beziehungen:

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: { } 

Produkt:

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: { } 

Die Setter und Getter Funktionen auch enthalten keine spezielle Tricks: die Tag.php Entity-Datei enthält:

/** 
* 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; 
} 

Während die product.php enthält:

/** 
* 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; 
} 

Ich habe auch versucht, ein $ this-> tags = new ArrayCollection(); an den Konstruktor des Produkts, aber es hat nichts geändert.

Auch gibt es kein Problem, Produkte hinzuzufügen, zu lesen und zu persistieren. Der Fehler wird ausgelöst, sobald ich $ em-> flush() aufruft.

Weiß jemand, warum meine Product-Entity eine Array-Sammlung erwartet? Ich habe ihm nie gesagt, dass er einen erwartet! Vielen Dank im Voraus!

Antwort

0

Ich fand schließlich heraus, was das seltsame Problem war. Danke Alexandr Cosoi für die Bestätigung, wie ich versucht habe, meine Entität hinzuzufügen. Das Problem war ein Konfigurationsfehler, den ich nicht bemerkt habe.

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

targetEntity wurde auf Produkt eingestellt, aber es musste auf "Tag" gesetzt werden. Das Ändern hat mein Problem wie erwartet gelöst.:)

+0

Hallo, habe gestern keine Antwort bekommen, aber da dies ein Konfigurationsproblem war, ist die Ausnahme, die du bekommen hast, noch seltsamer ... Und die Ausgabe deines Debugs erzeugt noch mehr Verwirrung, weil es korrekt ist :)) Doctrine \ ORM \ PersistentCollection ist korrekt, es ist ein Sammlungstyp, der von der Doktrin erstellt wird, wenn Daten von sql abgerufen werden. Es fungiert als eine ArrayCollection mit dem zusätzlichen Bonus, ein Ereignis auszulösen, wie zum Beispiel das Entfernen von Elementen. Jedenfalls bin ich froh, dass du es herausgefunden hast. –

2

Der Fehler besagt, dass die Eigenschaft "#tags" der Entität TestBundle \ Entity \ Product, die Sie versuchen zu leeren, ein Objekt vom Typ TestBundle \ Entity \ Tag anstelle einer Auflistung dieses Objekts enthält. Doctrine erwartet diese Auflistung/dieses Array, da die Metadaten für diese Eigenschaft angeben, dass sich TestBundle \ Entity \ Product in einem Viel-viele-Zustand mit TestBundle \ Entity \ Tag befindet und die Beziehung über die Eigenschaft "#tags" erfolgt. Dies sollte passieren, wenn:

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

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

//Or 

$this->tags[] = $tag; 

Aber der Code, den Sie hier veröffentlicht haben, sollte diese Ausnahme nicht erzeugen.

Sind Sie sicher, dass es keinen anderen Ort gibt, an dem eine Accessor-Methode aufgerufen wird, die die Tag-Eigenschaft von TestBundle \ Entity \ Product ändert? Etwas wie und Ereignis Listener?

+0

Ich fügte dem Setzer etwas Code hinzu, um zu überprüfen, ob der Setzer ausgeführt wird und was im Inneren passiert. 'code' echo get_class ($ this-> tags); echo get_class ($ tag); Dieser Code gibt Folgendes zurück: Lehre \ ORM \ PersistentCollection PretiumBundle \ Entity \ Tag Also, beide Typen die richtigen sind. Wie kann ich herausfinden, in welcher Zeile der Fehler passiert? Gibt es eine Möglichkeit, manuell in eine Sammlung zu konvertieren? –

Verwandte Themen