Doctrine flush()错误:类型" Doctrine \ Common \ Collections \ Collection | array"的预期值

时间:2016-05-06 11:26:20

标签: symfony orm doctrine many-to-many persist

我在Symfony(使用Doctrine)中使用多对多关系时遇到一个奇怪的问题,我以前在symfony项目中从未遇到多对多关系,我无法找到任何关系与其他项目的区别。

我有两个实体Product和Tag以及彼此之间的多对多关系。不幸的是,如果我尝试将产品添加到标签或反之,则错误

  

类型" Doctrine \ Common \ Collections \ Collection | array"的预期值for association field" TestBundle \ Entity \ Product#$ tags",got" TestBundle \ Entity \ Tag"代替。

出现。 用于向产品添加标记的代码:

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

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

    $em->flush();

当然,变量$ tag1和$ product都包含一个有效的实体。 用于多对多关系的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: {  }

setter和getter函数也不包含任何特殊技巧: 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实体需要数组集合吗?我从没告诉他期待一个人!非常感谢你提前!

2 个答案:

答案 0 :(得分: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的tags属性吗?像和事件监听器一样?

答案 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"。改变它只是按预期解决了我的问题。 :)