【发布时间】:2017-01-26 09:31:45
【问题描述】:
我对 Symfony3/doctrine2 和多对多的额外列有疑问。我刚开始用它开发
是的,我看到了帖子:Doctrine2: Best way to handle many-to-many with extra columns in reference table 但老实说,我不明白为什么它不适用于我的代码......
我被困两天了,在谷歌上看(他不是我的朋友),阅读文档......我的大脑不明白......
请帮我理解为什么。
问题
我有成员和地址实体。我想按成员的所有地址或按地址的所有成员。所以,多对多在 Doctrine 中。
在我的加入表上,我需要有一个额外的列favorite_address
所以,我需要有 3 个实体:Member、Address、MemberAddress
实体成员:
class Member implements AdvancedUserInterface
{
....
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Member\MemberAddress", mappedBy="member", cascade={"all"})
* @ORM\JoinTable(name="member_address",
* joinColumns={@ORM\JoinColumn(name="member_id", referencedColumnName="id")})
*/
private $addresses;
....
public function __construct(){
$this->addresses = new ArrayCollection();
}
/**
* Add an address
* @param Address $address
*/
public function addAddress(\AppBundle\Entity\Address\Address $address)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->addresses[] = $address;
}
/**
* Remove an address
* @param Address $address
*/
public function removeAddress(\AppBundle\Entity\Address\Address $address)
{
// Ici on utilise une méthode de l'ArrayCollection, pour supprimer la catégorie en argument
$this->addresses->removeElement($address);
}
/**
* Get all addresses
* @return ArrayCollection
*/
public function getAddresses()
{
return $this->addresses;
}
实体地址:
class Address
{
....
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Member\MemberAddress", mappedBy="address", cascade={"all"})
* @ORM\JoinTable(name="member_address",
* joinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id")})
*/
private $members;
....
/**
* Add a member
* @param Member $member
*/
public function addMember(\AppBundle\Entity\Member\Member $member)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->members[] = $member;
}
/**
* Remove a member
* @param Member $member
*/
public function removeMember(\AppBundle\Entity\Member\Member $member)
{
// Ici on utilise une méthode de l'ArrayCollection, pour supprimer la catégorie en argument
$this->members->removeElement($member);
}
/**
* Get all members
* @return ArrayCollection
*/
public function getMembers()
{
return $this->members;
}
最后一个实体:MemberAddressReference
class MemberAddress
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/** @ORM\ManyToOne(targetEntity="AppBundle\Entity\Member\Member", inversedBy="addresses")
* @ORM\JoinColumn(name="member_id", referencedColumnName="id")
*/
protected $member;
/** @ORM\ManyToOne(targetEntity="AppBundle\Entity\Address\Address", inversedBy="members")
* @ORM\JoinColumn(name="address_id", referencedColumnName="id")
*/
protected $address;
/** @ORM\Column(type="boolean") */
protected $isFavorite;
最后,控制器
class MemberAddressController extends Controller
{
public function createAction(Request $request){
....
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$currentDate = new \DateTime("now");
$em = $this->getDoctrine()->getManager();
$address = new Address();
$memberAddress = new MemberAddress();
$address->setType($form['type']->getData());
$address->setCreated($currentDate);
$address->setModified($currentDate);
$memberAddress->setMember($member);
$memberAddress->setAddress($address);
$memberAddress->setFavorite(1);
$em->persist($member);
$em->persist($address);
$em->persist($memberAddress);
$member->addAddress($address);
$em->flush();
dump($member);
die();
}
那么,怎么了
我收到此错误:
Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\Member\Member#$addresses", got "AppBundle\Entity\Address\Address" instead.
是的,类型不好,我明白,但为什么他不好?
public function addAddress(\AppBundle\Entity\Address\Address $address)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->addresses[] = $address;
}
addAddress 获取地址对象,不是吗?那么他为什么要等一个数组呢?
请帮帮我,我快疯了……
【问题讨论】:
-
@JoinTable注释不正确,应删除。它仅适用于没有额外属性的最简单的多对多关系。 -
好的,谢谢。我删除了它。但保存时仍然出错。
标签: symfony doctrine-orm