symfony 3不能从反面多次持久保存arraycollections

时间:2017-11-08 19:06:16

标签: doctrine-orm many-to-many symfony-3.3 arraycollection

我有3个实体,军队,武器和单位。有了军队和单位,我没有任何问题,但是当我坚持使用武器(它是军队和单位的反面)时,除了数组集合中的数据外,学说将全部保存在数据库中。

我在控制器中完成了dump($ weapon),并且使用我指定的所有元素创建了对象。

实体

武器(反面和数组集合不保存的那个)

    <?php

     namespace ArmyDataBundle\Entity;

    use Doctrine\ORM\Mapping as ORM;
    use Doctrine\Common\Collections\ArrayCollection;
    /**
   * Weapon
   *
   * @ORM\Table(name="weapon")
 *@ORM\Entity(repositoryClass="ArmyDataBundle\Repository\WeaponRepository")
 */
  class Weapon
   {
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 */
private $name;

/**
 * @var int
 *
 * @ORM\Column(name="distance", type="integer")
 */
private $distance;

/**
 * @var int
 *
 * @ORM\Column(name="f", type="integer")
 */
private $f;

/**
 * @var int
 *
 * @ORM\Column(name="fp", type="integer")
 */
private $fp;

/**
 * @var string
 *
 * @ORM\Column(name="type", type="string", length=255)
 */
private $type;

/**
 * @var int
 *
 * @ORM\Column(name="shoots", type="integer")
 */
private $shoots;

/**
 * Many Weapons have many Armies
 * @ORM\ManyToMany(targetEntity="ArmyDataBundle\Entity\Army", mappedBy="weapons")
 */
private $armies;

/**
 * Many Weapons have many Units
 * @ORM\ManyToMany(targetEntity="Unit", mappedBy="weapons")
 */
private $units;

public function __construct()
{
    $this->armies = new \Doctrine\Common\Collections\ArrayCollection();
    $this->units = new \Doctrine\Common\Collections\ArrayCollection();
}

/**
 * Get id
 *
 * @return int
 */
public function getId()
{
    return $this->id;
}

/**
 * Set name
 *
 * @param string $name
 *
 * @return Weapon
 */
public function setName($name)
{
    $this->name = $name;

    return $this;
}

/**
 * Get name
 *
 * @return string
 */
public function getName()
{
    return $this->name;
}

/**
 * Set distance
 *
 * @param integer $distance
 *
 * @return Weapon
 */
public function setDistance($distance)
{
    $this->distance = $distance;

    return $this;
}

/**
 * Get distance
 *
 * @return int
 */
public function getDistance()
{
    return $this->distance;
}

/**
 * Set f
 *
 * @param integer $f
 *
 * @return Weapon
 */
public function setF($f)
{
    $this->f = $f;

    return $this;
}

/**
 * Get f
 *
 * @return int
 */
public function getF()
{
    return $this->f;
}

/**
 * Set fp
 *
 * @param integer $fp
 *
 * @return Weapon
 */
public function setFp($fp)
{
    $this->fp = $fp;

    return $this;
}

/**
 * Get fp
 *
 * @return int
 */
public function getFp()
{
    return $this->fp;
}

/**
 * Set type
 *
 * @param string $type
 *
 * @return Weapon
 */
public function setType($type)
{
    $this->type = $type;

    return $this;
}

/**
 * Get type
 *
 * @return string
 */
public function getType()
{
    return $this->type;
}

/**
 * @return int
 */
public function getShoots()
{
    return $this->shoots;
}

/**
 * @param int $shoots
 */
public function setShoots($shoots)
{
    $this->shoots = $shoots;
}

/**
 * @return mixed
 */
public function getArmies()
{
    return $this->armies;
}

/**
 * @param mixed $armies
 */
public function setArmies($armies)
{
    $this->armies = $armies;
}

/**
 * @param mixed $units
 */
public function setUnits($units)
{
    $this->units = $units;
}



/**
 * Add army
 *
 * @param $army
 *
 * @return Weapon
 */
public function addArmies( \ArmyDataBundle\Entity\Army $army)
{
    if (!$this->armies->contains($army)){
        $army->addWeapons($this);
        $this->armies->add($army);
    }
    return $this;
}

/**
 * Remove army
 *
 * @param $army
 */
public function removeArmies( \ArmyDataBundle\Entity\Army $army)
{
    $this->armies->removeElement($army);
}

/**
 *
 */
public function clearArmies(){
    $this->armies->clear();
}

/**
 * @return mixed
 */
public function getUnits()
{
    return $this->units;
}

/**
 * Add unit
 *
 * @param $unit
 *
 * @return Weapon
 */
public function addUnits( \ArmyDataBundle\Entity\Unit $unit)
{
     if (!$this->units->contains($unit)){
         $this->units = $unit;
         $unit->addWeapons($this);
     }
    return $this;
}

/**
 * Remove unit
 *
 * @param $unit
 */
public function removeUnits( \ArmyDataBundle\Entity\Unit $unit)
{
    $this->units->removeElement($unit);
}

/**
 *
 */
public function clearUnits(){
    $this->units->clear();
}

public function __toString()
{
    return (String)$this->name;
}
}

军队

<?php

namespace ArmyDataBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
 * Army
 *
 * @ORM\Table(name="army")
 * 

@ORM\Entity(repositoryClass="ArmyDataBundle\Repository\ArmyRepository")
 */
    class Army
   {
    /**
     * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 */
private $name;

/**
 * One army has Many Units
 * @ORM\OneToMany(targetEntity="ArmyDataBundle\Entity\Unit", mappedBy="army")
 */
private $units;

/**
 * Many armies has Many Weapons
 * @ORM\ManyToMany(targetEntity="Weapon",cascade={"persist"}, inversedBy="armies")
 */
private $weapons;


public function __construct()
{
    $this->units = new \Doctrine\Common\Collections\ArrayCollection();
    $this->weapons = new \Doctrine\Common\Collections\ArrayCollection();
}

/**
 * Get id
 *
 * @return int
 */
public function getId()
{
    return $this->id;
}

/**
 * Set name
 *
 * @param string $name
 *
 * @return Army
 */
public function setName($name)
{
    $this->name = $name;

    return $this;
}

/**
 * Get name
 *
 * @return string
 */
public function getName()
{
    return $this->name;
}

public function __toString()
{
    return (String)$this->name;
}

/**
 * @return mixed
 */
public function getUnits()
{
    return $this->units;
}

public function addUnit( \ArmyDataBundle\Entity\Unit $unit)
{
    $unit->addWeapon($this);
    $this->units->add($unit);

    return $this;
}

/**
 * Remove unit
 *
 * @param $unit
 */
public function removeUnit( \ArmyDataBundle\Entity\Unit $unit)
{
    $this->units->removeElement($unit);
}

/**
 *
 */
public function clearUnits(){
    $this->units->clear();
}

/**
 * @return mixed
 */
public function getWeapons()
{
    return $this->weapons;
}

public function addWeapons( \ArmyDataBundle\Entity\Weapon $weapon)
{
    $weapon->addArmies($this);
    $this->weapons->add($weapon);

    return $this;
}

/**
 * Remove unit
 *
 * @param $unit
 */
public function removeWeapons( \ArmyDataBundle\Entity\Weapon $weapon)
{
    $this->weapons->removeElement($weapon);
}

/**
 *
 */
public function clearWeapons(){
    $this->weapons->clear();
}

}

单元

<?php

namespace ArmyDataBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Doctrine\Common\Collections\ArrayCollection;
/**
 * Unit
 *
 * @ORM\Table(name="unit")
 *  
@ORM\Entity(repositoryClass="ArmyDataBundle\Repository\UnitRepository")
 */
   class Unit
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 *
 */
private $name;

/**
 * @var int
 *
 * @ORM\Column(name="Ha", type="integer")
 */
private $ha;

/**
 * @var int
 *
 * @ORM\Column(name="Hp", type="integer")
 */
private $hp;

/**
 * @var int
 *
 * @ORM\Column(name="F", type="integer")
 */
private $f;

/**
 * @var int
 *
 * @ORM\Column(name="R", type="integer")
 */
private $r;

/**
 * @var int
 *
 * @ORM\Column(name="H", type="integer")
 */
private $h;

/**
 * @var int
 *
 * @ORM\Column(name="I", type="integer")
 */
private $i;

/**
 * @var int
 *
 * @ORM\Column(name="A", type="integer")
 */
private $a;

/**
 * @var int
 *
 * @ORM\Column(name="L", type="integer")
 */
private $l;

/**
 * @var int
 *
 * @ORM\Column(name="S", type="integer")
 */
private $s;

/**
 * Many Units have one Army
 * @ORM\ManyToOne(targetEntity="ArmyDataBundle\Entity\Army", inversedBy="units")
 * @ORM\JoinColumn(name="army_id", referencedColumnName="id")
 */
private $army;

/**
 * many units has Many Weapons
 * @ORM\ManyToMany(targetEntity="Weapon", cascade={"persist"}, inversedBy="units")
 */
private $weapons;

public function __construct()
{
    $this->weapons = new \Doctrine\Common\Collections\ArrayCollection();
}



/**
 * Get id
 *
 * @return int
 */
public function getId()
{
    return $this->id;
}

/**
 * Set name
 *
 * @param string $name
 *
 * @return Unit
 */
public function setName($name)
{
    $this->name = $name;

    return $this;
}

/**
 * Get name
 *
 * @return string
 */
public function getName()
{
    return $this->name;
}

/**
 * Set ha
 *
 * @param integer $ha
 *
 * @return Unit
 */
public function setHa($ha)
{
    $this->ha = $ha;

    return $this;
}

/**
 * Get ha
 *
 * @return int
 */
public function getHa()
{
    return $this->ha;
}

/**
 * Set hp
 *
 * @param integer $hp
 *
 * @return Unit
 */
public function setHp($hp)
{
    $this->hp = $hp;

    return $this;
}

/**
 * Get hp
 *
 * @return int
 */
public function getHp()
{
    return $this->hp;
}

/**
 * Set f
 *
 * @param integer $f
 *
 * @return Unit
 */
public function setF($f)
{
    $this->f = $f;

    return $this;
}

/**
 * Get f
 *
 * @return int
 */
public function getF()
{
    return $this->f;
}

/**
 * Set r
 *
 * @param integer $r
 *
 * @return Unit
 */
public function setR($r)
{
    $this->r = $r;

    return $this;
}

/**
 * Get r
 *
 * @return int
 */
public function getR()
{
    return $this->r;
}

/**
 * Set h
 *
 * @param integer $h
 *
 * @return Unit
 */
public function setH($h)
{
    $this->h = $h;

    return $this;
}

/**
 * Get h
 *
 * @return int
 */
public function getH()
{
    return $this->h;
}

/**
 * Set i
 *
 * @param integer $i
 *
 * @return Unit
 */
public function setI($i)
{
    $this->i = $i;

    return $this;
}

/**
 * Get i
 *
 * @return int
 */
public function getI()
{
    return $this->i;
}

/**
 * Set a
 *
 * @param integer $a
 *
 * @return Unit
 */
public function setA($a)
{
    $this->a = $a;

    return $this;
}

/**
 * Get a
 *
 * @return int
 */
public function getA()
{
    return $this->a;
}

/**
 * Set l
 *
 * @param integer $l
 *
 * @return Unit
 */
public function setL($l)
{
    $this->l = $l;

    return $this;
}

/**
 * Get l
 *
 * @return int
 */
public function getL()
{
    return $this->l;
}

/**
 * Set s
 *
 * @param integer $s
 *
 * @return Unit
 */
public function setS($s)
{
    $this->s = $s;

    return $this;
}

/**
 * Get s
 *
 * @return int
 */
public function getS()
{
    return $this->s;
}

/**
 * @return mixed
 */
public function getArmy()
{
    return $this->army;
}

/**
 * @param mixed $army
 */
public function setArmy($army)
{
    $this->army = $army;
}

/**
 * @return mixed
 */
public function getWeapons()
{
    return $this->weapons;
}

/**
 * @param mixed $weapons
 */
public function setWeapons($weapons)
{
    $this->weapons = $weapons;
}



public function addWeapons( \ArmyDataBundle\Entity\Weapon $weapon)
{
    if (!$this->weapons->contains($weapon)){
        $weapon->addUnits($this);
        $this->weapons->add($weapon);
    }
    return $this;
}

/**
 * Remove weapon
 *
 * @param $weapon
 */
public function removeWeapons( \ArmyDataBundle\Entity\Weapon $weapon)
{
    $this->weapons->removeElement($weapon);
}

/**
 *
 */
public function clearWeapons(){
    $this->weapons->clear();
}

public function __toString()
{
    return (String)$this->name;
}

}

这是控制器中的方法

 public function addAction(Request $request)
{
    $weapon = new Weapon();
    $form = $this->createForm('ArmyDataBundle\Form\WeaponType' , $weapon);

    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {

        $units = $weapon->getUnits();

        $em = $this->getDoctrine()->getManager();
        $em->persist($weapon);

        $em->flush($weapon);

        return $this->redirectToRoute('wp_index');
    }

    return $this->render('@ArmyData/Weapon/add_wp.html.twig', array(
        'weapon' => $weapon,
        'form' => $form->createView(),
    ));
}

<?php

namespace ArmyDataBundle\Form;

use ArmyDataBundle\Entity\Army;
use ArmyDataBundle\Entity\Unit;
use ArmyDataBundle\Entity\Weapon;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

use Symfony\Component\Form\Extension\Core\Type\CollectionType;

class WeaponType extends AbstractType
 {
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name', TextType::class, array('label' => 'weapon.nam'))
        ->add('distance', IntegerType::class, array('label' => 'weapon.ds'))
        ->add('f', ChoiceType::class, array('choices' => range(0, 10)))
        ->add('fp', ChoiceType::class, array('choices' => range(0, 10)))
        ->add('type', ChoiceType::class, array('choices' => array(
            'weapon.as' => 'Asalto',
            'weapon.ps' => 'Pesada',
            'weapon.rf' => 'Fuego Rapido',
            'weapon.ar' => 'Artilleria',
            ),'label'=> 'weapon.tp'
            ))
        ->add('shoots', IntegerType::class, array (
            'label'=> 'weapon.st'
            ))
        ->add('armies', CollectionType::class, [
            'entry_type' => EntityType::class,
            'entry_options' => [
                'class' => Army::class
            ],
            'label' => false,
            'allow_add' => true,
            'allow_delete' => true,
            'allow_extra_fields' => true,
            'by_reference' => false,
        ])
        ->add('units', CollectionType::class, [
            'entry_type' => EntityType::class,
            'entry_options' => [
                'class' => Unit::class
            ],
            'label' => false,
            'allow_add' => true,
            'allow_delete' => true,
            'allow_extra_fields' => true,
            'by_reference' => false,
        ])
    ;
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'ArmyDataBundle\Entity\Weapon' ,
    ));
}

public function getBlockPrefix()
{
    return 'weapon';
}
}

整个项目位于https://github.com/erethilclaw/AssaultW40k/tree/development

感谢您的关注。

1 个答案:

答案 0 :(得分:1)

好的,我最终解决了,我不知道是否是最好的方法,但我修改了控制器,现在有效。

public function addAction(Request $request)
{
    $weapon = new Weapon();
    $form = $this->createForm('ArmyDataBundle\Form\WeaponType' , $weapon);

    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $units = $weapon->getUnits();
        $armies = $weapon->getArmies();
        $em = $this->getDoctrine()->getManager();
        foreach ($armies as $army){
            $army->addWeapons($weapon);
            $em->persist($army);
            $em->flush($army);
        }
        foreach ($units as $unit){
            $unit->addWeapons($weapon);
            $em->persist($unit);
            $em->flush($unit);
        }
        $em->persist($weapon);
        $em->flush($weapon);

        return $this->redirectToRoute('wp_index');
    }