Doctrine flush() error: Expected value of type "Doctrine\Common\Collections\Collection|array"
Doctrine flush() error: Expected value of type "Doctrine\Common\Collections\Collection|array"
我在 Symfony(使用 Doctrine)中使用多对多关系时遇到一个奇怪的问题,我以前在 symfony 项目中从未遇到过多对多关系,我找不到任何区别其他项目。
我有两个实体 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 和$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 实体需要数组集合吗?我从来没有告诉他期待一个!非常感谢您!
错误告诉您,您要刷新的实体 TestBundle\Entity\Product 的 属性“#tags”包含类型为 TestBundle\Entity\Tag 的对象,而不是集合这个对象的。 Doctrine 期望这个 collection/array 因为 属性 的元数据表明 TestBundle\Entity\Product 与 TestBundle\Entity\Tag 处于多对多关系中,并且关系是通过 [=23= 完成的] “#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 的标签 属性 吗?类似事件监听器的东西?
终于知道是什么奇怪的问题了。感谢 Alexandr Cosoi 确认我尝试添加实体的方式。
问题是我没有注意到的配置错误。
manyToMany:
tags:
targetEntity: Product
inversedBy: products
joinTable:
name: tags2products
joinColumns:
tag_id:
referencedColumnName: id
inverseJoinColumns:
product_id:
referencedColumnName: id
targetEntity 已设置为 Product,但必须设置为 "Tag"。更改它只是按预期解决了我的问题。 :)
我在 Symfony(使用 Doctrine)中使用多对多关系时遇到一个奇怪的问题,我以前在 symfony 项目中从未遇到过多对多关系,我找不到任何区别其他项目。
我有两个实体 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 和$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 实体需要数组集合吗?我从来没有告诉他期待一个!非常感谢您!
错误告诉您,您要刷新的实体 TestBundle\Entity\Product 的 属性“#tags”包含类型为 TestBundle\Entity\Tag 的对象,而不是集合这个对象的。 Doctrine 期望这个 collection/array 因为 属性 的元数据表明 TestBundle\Entity\Product 与 TestBundle\Entity\Tag 处于多对多关系中,并且关系是通过 [=23= 完成的] “#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 的标签 属性 吗?类似事件监听器的东西?
终于知道是什么奇怪的问题了。感谢 Alexandr Cosoi 确认我尝试添加实体的方式。 问题是我没有注意到的配置错误。
manyToMany:
tags:
targetEntity: Product
inversedBy: products
joinTable:
name: tags2products
joinColumns:
tag_id:
referencedColumnName: id
inverseJoinColumns:
product_id:
referencedColumnName: id
targetEntity 已设置为 Product,但必须设置为 "Tag"。更改它只是按预期解决了我的问题。 :)